Whamcloud - gitweb
LU-15850 lmv: always space-balance r-r directories
[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
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2899                 grep "lfm_magic:.*0x0CD50CD0" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2901         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2902         # - sizeof(lfm_type) - sizeof(lfm_flags)
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2907         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2908                 grep "lfm_flags:.*0x0000DA05" ||
2909                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2910         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2911                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2913
2914         # file create in dir should fail
2915         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2916         touch $DIR/$tdir/${tdir}2/$tfile &&
2917                 error "$DIR/${tdir}2: file create should fail"
2918
2919         # chmod should work
2920         chmod 777 $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chmod failed"
2922         chmod 777 $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chmod failed"
2924
2925         # chown should work
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chown failed"
2928         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chown failed"
2930
2931         # rename should work
2932         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2934         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2936
2937         #remove foreign dir
2938         rmdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2940         rmdir $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2942 }
2943 run_test 27K "basic ops on dir with foreign LMV"
2944
2945 test_27L() {
2946         remote_mds_nodsh && skip "remote MDS with nodsh"
2947
2948         local POOL=${POOL:-$TESTNAME}
2949
2950         pool_add $POOL || error "pool_add failed"
2951
2952         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2953                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2954                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2955 }
2956 run_test 27L "lfs pool_list gives correct pool name"
2957
2958 test_27M() {
2959         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2960                 skip "Need MDS version >= than 2.12.57"
2961         remote_mds_nodsh && skip "remote MDS with nodsh"
2962         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2963
2964         # Set default striping on directory
2965         local setcount=4
2966         local stripe_opt
2967         local mdts=$(comma_list $(mdts_nodes))
2968
2969         # if we run against a 2.12 server which lacks overstring support
2970         # then the connect_flag will not report overstriping, even if client
2971         # is 2.14+
2972         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2973                 stripe_opt="-C $setcount"
2974         elif (( $OSTCOUNT >= $setcount )); then
2975                 stripe_opt="-c $setcount"
2976         else
2977                 skip "server does not support overstriping"
2978         fi
2979
2980         test_mkdir $DIR/$tdir
2981
2982         # Validate existing append_* params and ensure restore
2983         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2984         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2985         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2986
2987         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2988         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2989         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2990
2991         $LFS setstripe $stripe_opt $DIR/$tdir
2992
2993         echo 1 > $DIR/$tdir/${tfile}.1
2994         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2995         [ $count -eq $setcount ] ||
2996                 error "(1) stripe count $count, should be $setcount"
2997
2998         local appendcount=$orig_count
2999         echo 1 >> $DIR/$tdir/${tfile}.2_append
3000         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3001         [ $count -eq $appendcount ] ||
3002                 error "(2)stripe count $count, should be $appendcount for append"
3003
3004         # Disable O_APPEND striping, verify it works
3005         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3006
3007         # Should now get the default striping, which is 4
3008         setcount=4
3009         echo 1 >> $DIR/$tdir/${tfile}.3_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3011         [ $count -eq $setcount ] ||
3012                 error "(3) stripe count $count, should be $setcount"
3013
3014         # Try changing the stripe count for append files
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3016
3017         # Append striping is now 2 (directory default is still 4)
3018         appendcount=2
3019         echo 1 >> $DIR/$tdir/${tfile}.4_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3021         [ $count -eq $appendcount ] ||
3022                 error "(4) stripe count $count, should be $appendcount for append"
3023
3024         # Test append stripe count of -1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3026         appendcount=$OSTCOUNT
3027         echo 1 >> $DIR/$tdir/${tfile}.5
3028         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3029         [ $count -eq $appendcount ] ||
3030                 error "(5) stripe count $count, should be $appendcount for append"
3031
3032         # Set append striping back to default of 1
3033         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3034
3035         # Try a new default striping, PFL + DOM
3036         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3037
3038         # Create normal DOM file, DOM returns stripe count == 0
3039         setcount=0
3040         touch $DIR/$tdir/${tfile}.6
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3042         [ $count -eq $setcount ] ||
3043                 error "(6) stripe count $count, should be $setcount"
3044
3045         # Show
3046         appendcount=1
3047         echo 1 >> $DIR/$tdir/${tfile}.7_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3049         [ $count -eq $appendcount ] ||
3050                 error "(7) stripe count $count, should be $appendcount for append"
3051
3052         # Clean up DOM layout
3053         $LFS setstripe -d $DIR/$tdir
3054
3055         save_layout_restore_at_exit $MOUNT
3056         # Now test that append striping works when layout is from root
3057         $LFS setstripe -c 2 $MOUNT
3058         # Make a special directory for this
3059         mkdir $DIR/${tdir}/${tdir}.2
3060
3061         # Verify for normal file
3062         setcount=2
3063         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3064         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3065         [ $count -eq $setcount ] ||
3066                 error "(8) stripe count $count, should be $setcount"
3067
3068         appendcount=1
3069         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3070         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(9) stripe count $count, should be $appendcount for append"
3073
3074         # Now test O_APPEND striping with pools
3075         pool_add $TESTNAME || error "pool creation failed"
3076         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078
3079         echo 1 >> $DIR/$tdir/${tfile}.10_append
3080
3081         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3082         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3083
3084         # Check that count is still correct
3085         appendcount=1
3086         echo 1 >> $DIR/$tdir/${tfile}.11_append
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3088         [ $count -eq $appendcount ] ||
3089                 error "(11) stripe count $count, should be $appendcount for append"
3090
3091         # Disable O_APPEND stripe count, verify pool works separately
3092         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3093
3094         echo 1 >> $DIR/$tdir/${tfile}.12_append
3095
3096         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3097         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3098
3099         # Remove pool setting, verify it's not applied
3100         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3101
3102         echo 1 >> $DIR/$tdir/${tfile}.13_append
3103
3104         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3105         [ "$pool" = "" ] || error "(13) pool found: $pool"
3106 }
3107 run_test 27M "test O_APPEND striping"
3108
3109 test_27N() {
3110         combined_mgs_mds && skip "needs separate MGS/MDT"
3111
3112         pool_add $TESTNAME || error "pool_add failed"
3113         do_facet mgs "$LCTL pool_list $FSNAME" |
3114                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3115                 error "lctl pool_list on MGS failed"
3116 }
3117 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3118
3119 clean_foreign_symlink() {
3120         trap 0
3121         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3122         for i in $DIR/$tdir/* ; do
3123                 $LFS unlink_foreign $i || true
3124         done
3125 }
3126
3127 test_27O() {
3128         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3129                 skip "Need MDS version newer than 2.12.51"
3130
3131         test_mkdir $DIR/$tdir
3132         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3133         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3134
3135         trap clean_foreign_symlink EXIT
3136
3137         # enable foreign_symlink behaviour
3138         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3139
3140         # foreign symlink LOV format is a partial path by default
3141
3142         # create foreign file (lfs + API)
3143         $LFS setstripe --foreign=symlink --flags 0xda05 \
3144                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3145                 error "$DIR/$tdir/${tfile}: create failed"
3146
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_magic:.*0x0BD70BD0" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3150         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_flags:.*0x0000DA05" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3155         $LFS getstripe $DIR/$tdir/${tfile} |
3156                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3158
3159         # modify striping should fail
3160         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: setstripe should fail"
3162
3163         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3164         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3165         cat /etc/passwd > $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: write should fail"
3167
3168         # rename should succeed
3169         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3170                 error "$DIR/$tdir/$tfile: rename has failed"
3171
3172         #remove foreign_symlink file should fail
3173         rm $DIR/$tdir/${tfile}.new &&
3174                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3175
3176         #test fake symlink
3177         mkdir /tmp/${uuid1} ||
3178                 error "/tmp/${uuid1}: mkdir has failed"
3179         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3180                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3181         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3182         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3184         #read should succeed now
3185         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3186                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3187         #write should succeed now
3188         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3190         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3191                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3192         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3193                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3194
3195         #check that getstripe still works
3196         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3198
3199         # chmod should still succeed
3200         chmod 644 $DIR/$tdir/${tfile}.new ||
3201                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3202
3203         # chown should still succeed
3204         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3205                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3206
3207         # rename should still succeed
3208         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3209                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3210
3211         #remove foreign_symlink file should still fail
3212         rm $DIR/$tdir/${tfile} &&
3213                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3214
3215         #use special ioctl() to unlink foreign_symlink file
3216         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3217                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3218
3219 }
3220 run_test 27O "basic ops on foreign file of symlink type"
3221
3222 test_27P() {
3223         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3224                 skip "Need MDS version newer than 2.12.49"
3225
3226         test_mkdir $DIR/$tdir
3227         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3228         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3229
3230         trap clean_foreign_symlink EXIT
3231
3232         # enable foreign_symlink behaviour
3233         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3234
3235         # foreign symlink LMV format is a partial path by default
3236
3237         # create foreign dir (lfs + API)
3238         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3239                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3240                 error "$DIR/$tdir/${tdir}: create failed"
3241
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3243
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_magic:.*0x0CD50CD0" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3248                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3249         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3250                 grep "lfm_flags:.*0x0000DA05" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3252         $LFS getdirstripe $DIR/$tdir/${tdir} |
3253                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3255
3256         # file create in dir should fail
3257         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3258         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3259
3260         # rename should succeed
3261         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3262                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3263
3264         #remove foreign_symlink dir should fail
3265         rmdir $DIR/$tdir/${tdir}.new &&
3266                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3267
3268         #test fake symlink
3269         mkdir -p /tmp/${uuid1}/${uuid2} ||
3270                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3271         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3272                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3273         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3274         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3275                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3276         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3277                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3278
3279         #check that getstripe fails now that foreign_symlink enabled
3280         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3281                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3282
3283         # file create in dir should work now
3284         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3285                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3286         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3287                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3288         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3289                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3290
3291         # chmod should still succeed
3292         chmod 755 $DIR/$tdir/${tdir}.new ||
3293                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3294
3295         # chown should still succeed
3296         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3298
3299         # rename should still succeed
3300         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3301                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3302
3303         #remove foreign_symlink dir should still fail
3304         rmdir $DIR/$tdir/${tdir} &&
3305                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3306
3307         #use special ioctl() to unlink foreign_symlink file
3308         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3309                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3310
3311         #created file should still exist
3312         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3313                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3314         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3315                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3316 }
3317 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3318
3319 test_27Q() {
3320         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3321         stack_trap "rm -f $TMP/$tfile*"
3322
3323         test_mkdir $DIR/$tdir-1
3324         test_mkdir $DIR/$tdir-2
3325
3326         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3327         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3328
3329         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3330         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3331
3332         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3333         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3334
3335         # Create some bad symlinks and ensure that we don't loop
3336         # forever or something. These should return ELOOP (40) and
3337         # ENOENT (2) but I don't want to test for that because there's
3338         # always some weirdo architecture that needs to ruin
3339         # everything by defining these error numbers differently.
3340
3341         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3342         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3343
3344         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3345         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3346
3347         return 0
3348 }
3349 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3350
3351 test_27R() {
3352         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3353                 skip "need MDS 2.14.55 or later"
3354         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3355
3356         local testdir="$DIR/$tdir"
3357         test_mkdir -p $testdir
3358         stack_trap "rm -rf $testdir"
3359         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3360
3361         local f1="$testdir/f1"
3362         touch $f1 || error "failed to touch $f1"
3363         local count=$($LFS getstripe -c $f1)
3364         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3365
3366         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3367         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3368
3369         local maxcount=$(($OSTCOUNT - 1))
3370         local mdts=$(comma_list $(mdts_nodes))
3371         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3372         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3373
3374         local f2="$testdir/f2"
3375         touch $f2 || error "failed to touch $f2"
3376         local count=$($LFS getstripe -c $f2)
3377         (( $count == $maxcount )) || error "wrong stripe count"
3378 }
3379 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3380
3381 test_27S() {
3382         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3383                 skip "Need MDS version at least 2.14.54"
3384         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3385                 skip "needs different host for mdt1 ost1"
3386
3387         local count=$(precreated_ost_obj_count 0 0)
3388
3389         echo "precreate count $count"
3390         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3391         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3392         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3393         do_facet mds1 $LCTL set_param fail_loc=0x2109
3394         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3395         do_facet ost1 $LCTL set_param fail_loc=0x252
3396         createmany -o $DIR/$tdir/f $count &
3397         pid=$!
3398         echo "precreate count $(precreated_ost_obj_count 0 0)"
3399         do_facet mds1 $LCTL set_param fail_loc=0
3400         do_facet ost1 $LCTL set_param fail_loc=0
3401         wait $pid || error "createmany failed"
3402         echo "precreate count $(precreated_ost_obj_count 0 0)"
3403 }
3404 run_test 27S "don't deactivate OSP on network issue"
3405
3406 test_27T() {
3407         [ $(facet_host client) == $(facet_host ost1) ] &&
3408                 skip "need ost1 and client on different nodes"
3409
3410 #define OBD_FAIL_OSC_NO_GRANT            0x411
3411         $LCTL set_param fail_loc=0x20000411 fail_val=1
3412 #define OBD_FAIL_OST_ENOSPC              0x215
3413         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3414         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3415         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3416                 error "multiop failed"
3417 }
3418 run_test 27T "no eio on close on partial write due to enosp"
3419
3420 test_27U() {
3421         local dir=$DIR/$tdir
3422         local file=$dir/$tfile
3423         local append_pool=${TESTNAME}-append
3424         local normal_pool=${TESTNAME}-normal
3425         local pool
3426         local stripe_count
3427         local stripe_count2
3428         local mdts=$(comma_list $(mdts_nodes))
3429
3430         # FIMXE
3431         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3432         #       skip "Need MDS version at least 2.15.42"
3433
3434         # Validate existing append_* params and ensure restore
3435         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3436         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3437         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3438
3439         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3440         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3441         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3442
3443         pool_add $append_pool || error "pool creation failed"
3444         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3445
3446         pool_add $normal_pool || error "pool creation failed"
3447         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3448
3449         test_mkdir $dir
3450         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3451
3452         echo XXX >> $file.1
3453         $LFS getstripe $file.1
3454
3455         pool=$($LFS getstripe -p $file.1)
3456         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3457
3458         stripe_count2=$($LFS getstripe -c $file.1)
3459         ((stripe_count2 == stripe_count)) ||
3460                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3461
3462         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3463
3464         echo XXX >> $file.2
3465         $LFS getstripe $file.2
3466
3467         pool=$($LFS getstripe -p $file.2)
3468         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3469
3470         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3471
3472         echo XXX >> $file.3
3473         $LFS getstripe $file.3
3474
3475         stripe_count2=$($LFS getstripe -c $file.3)
3476         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3477 }
3478 run_test 27U "append pool and stripe count work with composite default layout"
3479
3480 # createtest also checks that device nodes are created and
3481 # then visible correctly (#2091)
3482 test_28() { # bug 2091
3483         test_mkdir $DIR/d28
3484         $CREATETEST $DIR/d28/ct || error "createtest failed"
3485 }
3486 run_test 28 "create/mknod/mkdir with bad file types ============"
3487
3488 test_29() {
3489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3490
3491         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3492                 disable_opencache
3493                 stack_trap "restore_opencache"
3494         }
3495
3496         sync; sleep 1; sync # flush out any dirty pages from previous tests
3497         cancel_lru_locks
3498         test_mkdir $DIR/d29
3499         touch $DIR/d29/foo
3500         log 'first d29'
3501         ls -l $DIR/d29
3502
3503         declare -i LOCKCOUNTORIG=0
3504         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3505                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3506         done
3507         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3508
3509         declare -i LOCKUNUSEDCOUNTORIG=0
3510         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3511                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3512         done
3513
3514         log 'second d29'
3515         ls -l $DIR/d29
3516         log 'done'
3517
3518         declare -i LOCKCOUNTCURRENT=0
3519         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3520                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3521         done
3522
3523         declare -i LOCKUNUSEDCOUNTCURRENT=0
3524         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3525                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3526         done
3527
3528         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3529                 $LCTL set_param -n ldlm.dump_namespaces ""
3530                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3531                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3532                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3533                 return 2
3534         fi
3535         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3536                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3537                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3538                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3539                 return 3
3540         fi
3541 }
3542 run_test 29 "IT_GETATTR regression  ============================"
3543
3544 test_30a() { # was test_30
3545         cp $(which ls) $DIR || cp /bin/ls $DIR
3546         $DIR/ls / || error "Can't execute binary from lustre"
3547         rm $DIR/ls
3548 }
3549 run_test 30a "execute binary from Lustre (execve) =============="
3550
3551 test_30b() {
3552         cp `which ls` $DIR || cp /bin/ls $DIR
3553         chmod go+rx $DIR/ls
3554         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3555         rm $DIR/ls
3556 }
3557 run_test 30b "execute binary from Lustre as non-root ==========="
3558
3559 test_30c() { # b=22376
3560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3561
3562         cp $(which ls) $DIR || cp /bin/ls $DIR
3563         chmod a-rw $DIR/ls
3564         cancel_lru_locks mdc
3565         cancel_lru_locks osc
3566         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3567         rm -f $DIR/ls
3568 }
3569 run_test 30c "execute binary from Lustre without read perms ===="
3570
3571 test_30d() {
3572         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3573
3574         for i in {1..10}; do
3575                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3576                 local PID=$!
3577                 sleep 1
3578                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3579                 wait $PID || error "executing dd from Lustre failed"
3580                 rm -f $DIR/$tfile
3581         done
3582
3583         rm -f $DIR/dd
3584 }
3585 run_test 30d "execute binary from Lustre while clear locks"
3586
3587 test_31a() {
3588         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3589         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3590 }
3591 run_test 31a "open-unlink file =================================="
3592
3593 test_31b() {
3594         touch $DIR/f31 || error "touch $DIR/f31 failed"
3595         ln $DIR/f31 $DIR/f31b || error "ln failed"
3596         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3597         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3598 }
3599 run_test 31b "unlink file with multiple links while open ======="
3600
3601 test_31c() {
3602         touch $DIR/f31 || error "touch $DIR/f31 failed"
3603         ln $DIR/f31 $DIR/f31c || error "ln failed"
3604         multiop_bg_pause $DIR/f31 O_uc ||
3605                 error "multiop_bg_pause for $DIR/f31 failed"
3606         MULTIPID=$!
3607         $MULTIOP $DIR/f31c Ouc
3608         kill -USR1 $MULTIPID
3609         wait $MULTIPID
3610 }
3611 run_test 31c "open-unlink file with multiple links ============="
3612
3613 test_31d() {
3614         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3615         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3616 }
3617 run_test 31d "remove of open directory ========================="
3618
3619 test_31e() { # bug 2904
3620         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3621 }
3622 run_test 31e "remove of open non-empty directory ==============="
3623
3624 test_31f() { # bug 4554
3625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3626
3627         set -vx
3628         test_mkdir $DIR/d31f
3629         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3630         cp /etc/hosts $DIR/d31f
3631         ls -l $DIR/d31f
3632         $LFS getstripe $DIR/d31f/hosts
3633         multiop_bg_pause $DIR/d31f D_c || return 1
3634         MULTIPID=$!
3635
3636         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3637         test_mkdir $DIR/d31f
3638         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3639         cp /etc/hosts $DIR/d31f
3640         ls -l $DIR/d31f
3641         $LFS getstripe $DIR/d31f/hosts
3642         multiop_bg_pause $DIR/d31f D_c || return 1
3643         MULTIPID2=$!
3644
3645         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3646         wait $MULTIPID || error "first opendir $MULTIPID failed"
3647
3648         sleep 6
3649
3650         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3651         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3652         set +vx
3653 }
3654 run_test 31f "remove of open directory with open-unlink file ==="
3655
3656 test_31g() {
3657         echo "-- cross directory link --"
3658         test_mkdir -c1 $DIR/${tdir}ga
3659         test_mkdir -c1 $DIR/${tdir}gb
3660         touch $DIR/${tdir}ga/f
3661         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3662         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3663         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3664         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3665         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3666 }
3667 run_test 31g "cross directory link==============="
3668
3669 test_31h() {
3670         echo "-- cross directory link --"
3671         test_mkdir -c1 $DIR/${tdir}
3672         test_mkdir -c1 $DIR/${tdir}/dir
3673         touch $DIR/${tdir}/f
3674         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3675         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3676         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3677         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3678         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3679 }
3680 run_test 31h "cross directory link under child==============="
3681
3682 test_31i() {
3683         echo "-- cross directory link --"
3684         test_mkdir -c1 $DIR/$tdir
3685         test_mkdir -c1 $DIR/$tdir/dir
3686         touch $DIR/$tdir/dir/f
3687         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3688         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3689         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3690         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3691         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3692 }
3693 run_test 31i "cross directory link under parent==============="
3694
3695 test_31j() {
3696         test_mkdir -c1 -p $DIR/$tdir
3697         test_mkdir -c1 -p $DIR/$tdir/dir1
3698         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3699         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3700         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3701         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3702         return 0
3703 }
3704 run_test 31j "link for directory==============="
3705
3706 test_31k() {
3707         test_mkdir -c1 -p $DIR/$tdir
3708         touch $DIR/$tdir/s
3709         touch $DIR/$tdir/exist
3710         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3711         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3712         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3713         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3714         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3715         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3716         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3717         return 0
3718 }
3719 run_test 31k "link to file: the same, non-existing, dir==============="
3720
3721 test_31m() {
3722         mkdir $DIR/d31m
3723         touch $DIR/d31m/s
3724         mkdir $DIR/d31m2
3725         touch $DIR/d31m2/exist
3726         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3727         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3728         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3729         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3730         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3731         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3732         return 0
3733 }
3734 run_test 31m "link to file: the same, non-existing, dir==============="
3735
3736 test_31n() {
3737         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3738         nlink=$(stat --format=%h $DIR/$tfile)
3739         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3740         local fd=$(free_fd)
3741         local cmd="exec $fd<$DIR/$tfile"
3742         eval $cmd
3743         cmd="exec $fd<&-"
3744         trap "eval $cmd" EXIT
3745         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3746         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3747         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3748         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3749         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3750         eval $cmd
3751 }
3752 run_test 31n "check link count of unlinked file"
3753
3754 link_one() {
3755         local tempfile=$(mktemp $1_XXXXXX)
3756         mlink $tempfile $1 2> /dev/null &&
3757                 echo "$BASHPID: link $tempfile to $1 succeeded"
3758         munlink $tempfile
3759 }
3760
3761 test_31o() { # LU-2901
3762         test_mkdir $DIR/$tdir
3763         for LOOP in $(seq 100); do
3764                 rm -f $DIR/$tdir/$tfile*
3765                 for THREAD in $(seq 8); do
3766                         link_one $DIR/$tdir/$tfile.$LOOP &
3767                 done
3768                 wait
3769                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3770                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3771                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3772                         break || true
3773         done
3774 }
3775 run_test 31o "duplicate hard links with same filename"
3776
3777 test_31p() {
3778         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3779
3780         test_mkdir $DIR/$tdir
3781         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3782         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3783
3784         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3785                 error "open unlink test1 failed"
3786         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3787                 error "open unlink test2 failed"
3788
3789         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3790                 error "test1 still exists"
3791         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3792                 error "test2 still exists"
3793 }
3794 run_test 31p "remove of open striped directory"
3795
3796 test_31q() {
3797         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3798
3799         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3800         index=$($LFS getdirstripe -i $DIR/$tdir)
3801         [ $index -eq 3 ] || error "first stripe index $index != 3"
3802         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3803         [ $index -eq 1 ] || error "second stripe index $index != 1"
3804
3805         # when "-c <stripe_count>" is set, the number of MDTs specified after
3806         # "-i" should equal to the stripe count
3807         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3808 }
3809 run_test 31q "create striped directory on specific MDTs"
3810
3811 #LU-14949
3812 test_31r() {
3813         touch $DIR/$tfile.target
3814         touch $DIR/$tfile.source
3815
3816         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3817         $LCTL set_param fail_loc=0x1419 fail_val=3
3818         cat $DIR/$tfile.target &
3819         CATPID=$!
3820
3821         # Guarantee open is waiting before we get here
3822         sleep 1
3823         mv $DIR/$tfile.source $DIR/$tfile.target
3824
3825         wait $CATPID
3826         RC=$?
3827         if [[ $RC -ne 0 ]]; then
3828                 error "open with cat failed, rc=$RC"
3829         fi
3830 }
3831 run_test 31r "open-rename(replace) race"
3832
3833 cleanup_test32_mount() {
3834         local rc=0
3835         trap 0
3836         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3837         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3838         losetup -d $loopdev || true
3839         rm -rf $DIR/$tdir
3840         return $rc
3841 }
3842
3843 test_32a() {
3844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3845
3846         echo "== more mountpoints and symlinks ================="
3847         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3848         trap cleanup_test32_mount EXIT
3849         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3850         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3851                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3852         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3853                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3854         cleanup_test32_mount
3855 }
3856 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3857
3858 test_32b() {
3859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3860
3861         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3862         trap cleanup_test32_mount EXIT
3863         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3864         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3865                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3866         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3867                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3868         cleanup_test32_mount
3869 }
3870 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3871
3872 test_32c() {
3873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3874
3875         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3876         trap cleanup_test32_mount EXIT
3877         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3878         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3879                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3880         test_mkdir -p $DIR/$tdir/d2/test_dir
3881         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3882                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3883         cleanup_test32_mount
3884 }
3885 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3886
3887 test_32d() {
3888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3889
3890         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3891         trap cleanup_test32_mount EXIT
3892         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3893         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3894                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3895         test_mkdir -p $DIR/$tdir/d2/test_dir
3896         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3897                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3898         cleanup_test32_mount
3899 }
3900 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3901
3902 test_32e() {
3903         rm -fr $DIR/$tdir
3904         test_mkdir -p $DIR/$tdir/tmp
3905         local tmp_dir=$DIR/$tdir/tmp
3906         ln -s $DIR/$tdir $tmp_dir/symlink11
3907         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3908         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3909         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3910 }
3911 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3912
3913 test_32f() {
3914         rm -fr $DIR/$tdir
3915         test_mkdir -p $DIR/$tdir/tmp
3916         local tmp_dir=$DIR/$tdir/tmp
3917         ln -s $DIR/$tdir $tmp_dir/symlink11
3918         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3919         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3920         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3921 }
3922 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3923
3924 test_32g() {
3925         local tmp_dir=$DIR/$tdir/tmp
3926         test_mkdir -p $tmp_dir
3927         test_mkdir $DIR/${tdir}2
3928         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3929         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3930         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3931         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3932         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3933         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3934 }
3935 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3936
3937 test_32h() {
3938         rm -fr $DIR/$tdir $DIR/${tdir}2
3939         tmp_dir=$DIR/$tdir/tmp
3940         test_mkdir -p $tmp_dir
3941         test_mkdir $DIR/${tdir}2
3942         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3943         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3944         ls $tmp_dir/symlink12 || error "listing symlink12"
3945         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3946 }
3947 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3948
3949 test_32i() {
3950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3951
3952         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3953         trap cleanup_test32_mount EXIT
3954         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3955         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3956                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3957         touch $DIR/$tdir/test_file
3958         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3959                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3960         cleanup_test32_mount
3961 }
3962 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3963
3964 test_32j() {
3965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3966
3967         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3968         trap cleanup_test32_mount EXIT
3969         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3970         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3971                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3972         touch $DIR/$tdir/test_file
3973         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3974                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3975         cleanup_test32_mount
3976 }
3977 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3978
3979 test_32k() {
3980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3981
3982         rm -fr $DIR/$tdir
3983         trap cleanup_test32_mount EXIT
3984         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3985         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3986                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3987         test_mkdir -p $DIR/$tdir/d2
3988         touch $DIR/$tdir/d2/test_file || error "touch failed"
3989         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3990                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3991         cleanup_test32_mount
3992 }
3993 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3994
3995 test_32l() {
3996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3997
3998         rm -fr $DIR/$tdir
3999         trap cleanup_test32_mount EXIT
4000         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4001         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4002                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4003         test_mkdir -p $DIR/$tdir/d2
4004         touch $DIR/$tdir/d2/test_file || error "touch failed"
4005         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4006                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4007         cleanup_test32_mount
4008 }
4009 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4010
4011 test_32m() {
4012         rm -fr $DIR/d32m
4013         test_mkdir -p $DIR/d32m/tmp
4014         TMP_DIR=$DIR/d32m/tmp
4015         ln -s $DIR $TMP_DIR/symlink11
4016         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4017         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4018                 error "symlink11 not a link"
4019         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4020                 error "symlink01 not a link"
4021 }
4022 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4023
4024 test_32n() {
4025         rm -fr $DIR/d32n
4026         test_mkdir -p $DIR/d32n/tmp
4027         TMP_DIR=$DIR/d32n/tmp
4028         ln -s $DIR $TMP_DIR/symlink11
4029         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4030         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4031         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4032 }
4033 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4034
4035 test_32o() {
4036         touch $DIR/$tfile
4037         test_mkdir -p $DIR/d32o/tmp
4038         TMP_DIR=$DIR/d32o/tmp
4039         ln -s $DIR/$tfile $TMP_DIR/symlink12
4040         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4041         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4042                 error "symlink12 not a link"
4043         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4044         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4045                 error "$DIR/d32o/tmp/symlink12 not file type"
4046         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4047                 error "$DIR/d32o/symlink02 not file type"
4048 }
4049 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4050
4051 test_32p() {
4052         log 32p_1
4053         rm -fr $DIR/d32p
4054         log 32p_2
4055         rm -f $DIR/$tfile
4056         log 32p_3
4057         touch $DIR/$tfile
4058         log 32p_4
4059         test_mkdir -p $DIR/d32p/tmp
4060         log 32p_5
4061         TMP_DIR=$DIR/d32p/tmp
4062         log 32p_6
4063         ln -s $DIR/$tfile $TMP_DIR/symlink12
4064         log 32p_7
4065         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4066         log 32p_8
4067         cat $DIR/d32p/tmp/symlink12 ||
4068                 error "Can't open $DIR/d32p/tmp/symlink12"
4069         log 32p_9
4070         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4071         log 32p_10
4072 }
4073 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4074
4075 test_32q() {
4076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4077
4078         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4079         trap cleanup_test32_mount EXIT
4080         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4081         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4082         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4083                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4084         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4085         cleanup_test32_mount
4086 }
4087 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4088
4089 test_32r() {
4090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4091
4092         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4093         trap cleanup_test32_mount EXIT
4094         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4095         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4096         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4097                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4098         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4099         cleanup_test32_mount
4100 }
4101 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4102
4103 test_33aa() {
4104         rm -f $DIR/$tfile
4105         touch $DIR/$tfile
4106         chmod 444 $DIR/$tfile
4107         chown $RUNAS_ID $DIR/$tfile
4108         log 33_1
4109         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4110         log 33_2
4111 }
4112 run_test 33aa "write file with mode 444 (should return error)"
4113
4114 test_33a() {
4115         rm -fr $DIR/$tdir
4116         test_mkdir $DIR/$tdir
4117         chown $RUNAS_ID $DIR/$tdir
4118         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4119                 error "$RUNAS create $tdir/$tfile failed"
4120         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4121                 error "open RDWR" || true
4122 }
4123 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4124
4125 test_33b() {
4126         rm -fr $DIR/$tdir
4127         test_mkdir $DIR/$tdir
4128         chown $RUNAS_ID $DIR/$tdir
4129         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4130 }
4131 run_test 33b "test open file with malformed flags (No panic)"
4132
4133 test_33c() {
4134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4135         remote_ost_nodsh && skip "remote OST with nodsh"
4136
4137         local ostnum
4138         local ostname
4139         local write_bytes
4140         local all_zeros
4141
4142         all_zeros=true
4143         test_mkdir $DIR/$tdir
4144         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4145
4146         sync
4147         for ostnum in $(seq $OSTCOUNT); do
4148                 # test-framework's OST numbering is one-based, while Lustre's
4149                 # is zero-based
4150                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4151                 # check if at least some write_bytes stats are counted
4152                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4153                               obdfilter.$ostname.stats |
4154                               awk '/^write_bytes/ {print $7}' )
4155                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4156                 if (( ${write_bytes:-0} > 0 )); then
4157                         all_zeros=false
4158                         break
4159                 fi
4160         done
4161
4162         $all_zeros || return 0
4163
4164         # Write four bytes
4165         echo foo > $DIR/$tdir/bar
4166         # Really write them
4167         sync
4168
4169         # Total up write_bytes after writing.  We'd better find non-zeros.
4170         for ostnum in $(seq $OSTCOUNT); do
4171                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4172                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4173                               obdfilter/$ostname/stats |
4174                               awk '/^write_bytes/ {print $7}' )
4175                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4176                 if (( ${write_bytes:-0} > 0 )); then
4177                         all_zeros=false
4178                         break
4179                 fi
4180         done
4181
4182         if $all_zeros; then
4183                 for ostnum in $(seq $OSTCOUNT); do
4184                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4185                         echo "Check write_bytes is in obdfilter.*.stats:"
4186                         do_facet ost$ostnum lctl get_param -n \
4187                                 obdfilter.$ostname.stats
4188                 done
4189                 error "OST not keeping write_bytes stats (b=22312)"
4190         fi
4191 }
4192 run_test 33c "test write_bytes stats"
4193
4194 test_33d() {
4195         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4197
4198         local MDTIDX=1
4199         local remote_dir=$DIR/$tdir/remote_dir
4200
4201         test_mkdir $DIR/$tdir
4202         $LFS mkdir -i $MDTIDX $remote_dir ||
4203                 error "create remote directory failed"
4204
4205         touch $remote_dir/$tfile
4206         chmod 444 $remote_dir/$tfile
4207         chown $RUNAS_ID $remote_dir/$tfile
4208
4209         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4210
4211         chown $RUNAS_ID $remote_dir
4212         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4213                                         error "create" || true
4214         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4215                                     error "open RDWR" || true
4216         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4217 }
4218 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4219
4220 test_33e() {
4221         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4222
4223         mkdir $DIR/$tdir
4224
4225         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4226         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4227         mkdir $DIR/$tdir/local_dir
4228
4229         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4230         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4231         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4232
4233         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4234                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4235
4236         rmdir $DIR/$tdir/* || error "rmdir failed"
4237
4238         umask 777
4239         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4240         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4241         mkdir $DIR/$tdir/local_dir
4242
4243         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4244         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4245         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4246
4247         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4248                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4249
4250         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4251
4252         umask 000
4253         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4254         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4255         mkdir $DIR/$tdir/local_dir
4256
4257         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4258         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4259         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4260
4261         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4262                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4263 }
4264 run_test 33e "mkdir and striped directory should have same mode"
4265
4266 cleanup_33f() {
4267         trap 0
4268         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4269 }
4270
4271 test_33f() {
4272         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4273         remote_mds_nodsh && skip "remote MDS with nodsh"
4274
4275         mkdir $DIR/$tdir
4276         chmod go+rwx $DIR/$tdir
4277         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4278         trap cleanup_33f EXIT
4279
4280         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4281                 error "cannot create striped directory"
4282
4283         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4284                 error "cannot create files in striped directory"
4285
4286         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4287                 error "cannot remove files in striped directory"
4288
4289         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4290                 error "cannot remove striped directory"
4291
4292         cleanup_33f
4293 }
4294 run_test 33f "nonroot user can create, access, and remove a striped directory"
4295
4296 test_33g() {
4297         mkdir -p $DIR/$tdir/dir2
4298
4299         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4300         echo $err
4301         [[ $err =~ "exists" ]] || error "Not exists error"
4302 }
4303 run_test 33g "nonroot user create already existing root created file"
4304
4305 sub_33h() {
4306         local hash_type=$1
4307         local count=250
4308
4309         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4310                 error "lfs mkdir -H $hash_type $tdir failed"
4311         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4312
4313         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4314         local index2
4315         local fname
4316
4317         for fname in $DIR/$tdir/$tfile.bak \
4318                      $DIR/$tdir/$tfile.SAV \
4319                      $DIR/$tdir/$tfile.orig \
4320                      $DIR/$tdir/$tfile~; do
4321                 touch $fname || error "touch $fname failed"
4322                 index2=$($LFS getstripe -m $fname)
4323                 (( $index == $index2 )) ||
4324                         error "$fname MDT index mismatch $index != $index2"
4325         done
4326
4327         local failed=0
4328         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4329         local pattern
4330
4331         for pattern in ${patterns[*]}; do
4332                 echo "pattern $pattern"
4333                 fname=$DIR/$tdir/$pattern
4334                 for (( i = 0; i < $count; i++ )); do
4335                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4336                                 error "mktemp $DIR/$tdir/$pattern failed"
4337                         index2=$($LFS getstripe -m $fname)
4338                         (( $index == $index2 )) && continue
4339
4340                         failed=$((failed + 1))
4341                         echo "$fname MDT index mismatch $index != $index2"
4342                 done
4343         done
4344
4345         echo "$failed/$count MDT index mismatches, expect ~2-4"
4346         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4347
4348         local same=0
4349         local expect
4350
4351         # verify that "crush" is still broken with all files on same MDT,
4352         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4353         [[ "$hash_type" == "crush" ]] && expect=$count ||
4354                 expect=$((count / MDSCOUNT))
4355
4356         # crush2 doesn't put all-numeric suffixes on the same MDT,
4357         # filename like $tfile.12345678 should *not* be considered temp
4358         for pattern in ${patterns[*]}; do
4359                 local base=${pattern%%X*}
4360                 local suff=${pattern#$base}
4361
4362                 echo "pattern $pattern"
4363                 for (( i = 0; i < $count; i++ )); do
4364                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4365                         touch $fname || error "touch $fname failed"
4366                         index2=$($LFS getstripe -m $fname)
4367                         (( $index != $index2 )) && continue
4368
4369                         same=$((same + 1))
4370                 done
4371         done
4372
4373         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4374         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4375            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4376                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4377         same=0
4378
4379         # crush2 doesn't put suffixes with special characters on the same MDT
4380         # filename like $tfile.txt.1234 should *not* be considered temp
4381         for pattern in ${patterns[*]}; do
4382                 local base=${pattern%%X*}
4383                 local suff=${pattern#$base}
4384
4385                 pattern=$base...${suff/XXX}
4386                 echo "pattern=$pattern"
4387                 for (( i = 0; i < $count; i++ )); do
4388                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4389                                 error "touch $fname failed"
4390                         index2=$($LFS getstripe -m $fname)
4391                         (( $index != $index2 )) && continue
4392
4393                         same=$((same + 1))
4394                 done
4395         done
4396
4397         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4398         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4399            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4400                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4401 }
4402
4403 test_33h() {
4404         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4405         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4406                 skip "Need MDS version at least 2.13.50"
4407
4408         sub_33h crush
4409 }
4410 run_test 33h "temp file is located on the same MDT as target (crush)"
4411
4412 test_33hh() {
4413         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4414         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4415         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4416                 skip "Need MDS version at least 2.15.0 for crush2"
4417
4418         sub_33h crush2
4419 }
4420 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4421
4422 test_33i()
4423 {
4424         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4425
4426         local FNAME=$(str_repeat 'f' 250)
4427
4428         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4429         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4430
4431         local count
4432         local total
4433
4434         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4435
4436         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4437
4438         lctl --device %$MDC deactivate
4439         stack_trap "lctl --device %$MDC activate"
4440         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4441         total=$(\ls -l $DIR/$tdir | wc -l)
4442         # "ls -l" will list total in the first line
4443         total=$((total - 1))
4444         (( total + count == 1000 )) ||
4445                 error "ls list $total files, $count files on MDT1"
4446 }
4447 run_test 33i "striped directory can be accessed when one MDT is down"
4448
4449 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4450 test_34a() {
4451         rm -f $DIR/f34
4452         $MCREATE $DIR/f34 || error "mcreate failed"
4453         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4454                 error "getstripe failed"
4455         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4456         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4457                 error "getstripe failed"
4458         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4459                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4460 }
4461 run_test 34a "truncate file that has not been opened ==========="
4462
4463 test_34b() {
4464         [ ! -f $DIR/f34 ] && test_34a
4465         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4466                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4467         $OPENFILE -f O_RDONLY $DIR/f34
4468         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4469                 error "getstripe failed"
4470         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4471                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4472 }
4473 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4474
4475 test_34c() {
4476         [ ! -f $DIR/f34 ] && test_34a
4477         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4478                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4479         $OPENFILE -f O_RDWR $DIR/f34
4480         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4481                 error "$LFS getstripe failed"
4482         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4483                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4484 }
4485 run_test 34c "O_RDWR opening file-with-size works =============="
4486
4487 test_34d() {
4488         [ ! -f $DIR/f34 ] && test_34a
4489         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4490                 error "dd failed"
4491         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4492                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4493         rm $DIR/f34
4494 }
4495 run_test 34d "write to sparse file ============================="
4496
4497 test_34e() {
4498         rm -f $DIR/f34e
4499         $MCREATE $DIR/f34e || error "mcreate failed"
4500         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4501         $CHECKSTAT -s 1000 $DIR/f34e ||
4502                 error "Size of $DIR/f34e not equal to 1000 bytes"
4503         $OPENFILE -f O_RDWR $DIR/f34e
4504         $CHECKSTAT -s 1000 $DIR/f34e ||
4505                 error "Size of $DIR/f34e not equal to 1000 bytes"
4506 }
4507 run_test 34e "create objects, some with size and some without =="
4508
4509 test_34f() { # bug 6242, 6243
4510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4511
4512         SIZE34F=48000
4513         rm -f $DIR/f34f
4514         $MCREATE $DIR/f34f || error "mcreate failed"
4515         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4516         dd if=$DIR/f34f of=$TMP/f34f
4517         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4518         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4519         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4520         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4521         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4522 }
4523 run_test 34f "read from a file with no objects until EOF ======="
4524
4525 test_34g() {
4526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4527
4528         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4529                 error "dd failed"
4530         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4531         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4532                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4533         cancel_lru_locks osc
4534         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4535                 error "wrong size after lock cancel"
4536
4537         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4538         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4539                 error "expanding truncate failed"
4540         cancel_lru_locks osc
4541         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4542                 error "wrong expanded size after lock cancel"
4543 }
4544 run_test 34g "truncate long file ==============================="
4545
4546 test_34h() {
4547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4548
4549         local gid=10
4550         local sz=1000
4551
4552         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4553         sync # Flush the cache so that multiop below does not block on cache
4554              # flush when getting the group lock
4555         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4556         MULTIPID=$!
4557
4558         # Since just timed wait is not good enough, let's do a sync write
4559         # that way we are sure enough time for a roundtrip + processing
4560         # passed + 2 seconds of extra margin.
4561         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4562         rm $DIR/${tfile}-1
4563         sleep 2
4564
4565         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4566                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4567                 kill -9 $MULTIPID
4568         fi
4569         wait $MULTIPID
4570         local nsz=`stat -c %s $DIR/$tfile`
4571         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4572 }
4573 run_test 34h "ftruncate file under grouplock should not block"
4574
4575 test_35a() {
4576         cp /bin/sh $DIR/f35a
4577         chmod 444 $DIR/f35a
4578         chown $RUNAS_ID $DIR/f35a
4579         $RUNAS $DIR/f35a && error || true
4580         rm $DIR/f35a
4581 }
4582 run_test 35a "exec file with mode 444 (should return and not leak)"
4583
4584 test_36a() {
4585         rm -f $DIR/f36
4586         utime $DIR/f36 || error "utime failed for MDS"
4587 }
4588 run_test 36a "MDS utime check (mknod, utime)"
4589
4590 test_36b() {
4591         echo "" > $DIR/f36
4592         utime $DIR/f36 || error "utime failed for OST"
4593 }
4594 run_test 36b "OST utime check (open, utime)"
4595
4596 test_36c() {
4597         rm -f $DIR/d36/f36
4598         test_mkdir $DIR/d36
4599         chown $RUNAS_ID $DIR/d36
4600         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4601 }
4602 run_test 36c "non-root MDS utime check (mknod, utime)"
4603
4604 test_36d() {
4605         [ ! -d $DIR/d36 ] && test_36c
4606         echo "" > $DIR/d36/f36
4607         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4608 }
4609 run_test 36d "non-root OST utime check (open, utime)"
4610
4611 test_36e() {
4612         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4613
4614         test_mkdir $DIR/$tdir
4615         touch $DIR/$tdir/$tfile
4616         $RUNAS utime $DIR/$tdir/$tfile &&
4617                 error "utime worked, expected failure" || true
4618 }
4619 run_test 36e "utime on non-owned file (should return error)"
4620
4621 subr_36fh() {
4622         local fl="$1"
4623         local LANG_SAVE=$LANG
4624         local LC_LANG_SAVE=$LC_LANG
4625         export LANG=C LC_LANG=C # for date language
4626
4627         DATESTR="Dec 20  2000"
4628         test_mkdir $DIR/$tdir
4629         lctl set_param fail_loc=$fl
4630         date; date +%s
4631         cp /etc/hosts $DIR/$tdir/$tfile
4632         sync & # write RPC generated with "current" inode timestamp, but delayed
4633         sleep 1
4634         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4635         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4636         cancel_lru_locks $OSC
4637         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4638         date; date +%s
4639         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4640                 echo "BEFORE: $LS_BEFORE" && \
4641                 echo "AFTER : $LS_AFTER" && \
4642                 echo "WANT  : $DATESTR" && \
4643                 error "$DIR/$tdir/$tfile timestamps changed" || true
4644
4645         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4646 }
4647
4648 test_36f() {
4649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4650
4651         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4652         subr_36fh "0x80000214"
4653 }
4654 run_test 36f "utime on file racing with OST BRW write =========="
4655
4656 test_36g() {
4657         remote_ost_nodsh && skip "remote OST with nodsh"
4658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4659         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4660                 skip "Need MDS version at least 2.12.51"
4661
4662         local fmd_max_age
4663         local fmd
4664         local facet="ost1"
4665         local tgt="obdfilter"
4666
4667         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4668
4669         test_mkdir $DIR/$tdir
4670         fmd_max_age=$(do_facet $facet \
4671                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4672                 head -n 1")
4673
4674         echo "FMD max age: ${fmd_max_age}s"
4675         touch $DIR/$tdir/$tfile
4676         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4677                 gawk '{cnt=cnt+$1}  END{print cnt}')
4678         echo "FMD before: $fmd"
4679         [[ $fmd == 0 ]] &&
4680                 error "FMD wasn't create by touch"
4681         sleep $((fmd_max_age + 12))
4682         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4683                 gawk '{cnt=cnt+$1}  END{print cnt}')
4684         echo "FMD after: $fmd"
4685         [[ $fmd == 0 ]] ||
4686                 error "FMD wasn't expired by ping"
4687 }
4688 run_test 36g "FMD cache expiry ====================="
4689
4690 test_36h() {
4691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4692
4693         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4694         subr_36fh "0x80000227"
4695 }
4696 run_test 36h "utime on file racing with OST BRW write =========="
4697
4698 test_36i() {
4699         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4700
4701         test_mkdir $DIR/$tdir
4702         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4703
4704         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4705         local new_mtime=$((mtime + 200))
4706
4707         #change Modify time of striped dir
4708         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4709                         error "change mtime failed"
4710
4711         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4712
4713         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4714 }
4715 run_test 36i "change mtime on striped directory"
4716
4717 # test_37 - duplicate with tests 32q 32r
4718
4719 test_38() {
4720         local file=$DIR/$tfile
4721         touch $file
4722         openfile -f O_DIRECTORY $file
4723         local RC=$?
4724         local ENOTDIR=20
4725         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4726         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4727 }
4728 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4729
4730 test_39a() { # was test_39
4731         touch $DIR/$tfile
4732         touch $DIR/${tfile}2
4733 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4734 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4735 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4736         sleep 2
4737         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4738         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4739                 echo "mtime"
4740                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4741                 echo "atime"
4742                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4743                 echo "ctime"
4744                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4745                 error "O_TRUNC didn't change timestamps"
4746         fi
4747 }
4748 run_test 39a "mtime changed on create"
4749
4750 test_39b() {
4751         test_mkdir -c1 $DIR/$tdir
4752         cp -p /etc/passwd $DIR/$tdir/fopen
4753         cp -p /etc/passwd $DIR/$tdir/flink
4754         cp -p /etc/passwd $DIR/$tdir/funlink
4755         cp -p /etc/passwd $DIR/$tdir/frename
4756         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4757
4758         sleep 1
4759         echo "aaaaaa" >> $DIR/$tdir/fopen
4760         echo "aaaaaa" >> $DIR/$tdir/flink
4761         echo "aaaaaa" >> $DIR/$tdir/funlink
4762         echo "aaaaaa" >> $DIR/$tdir/frename
4763
4764         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4765         local link_new=`stat -c %Y $DIR/$tdir/flink`
4766         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4767         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4768
4769         cat $DIR/$tdir/fopen > /dev/null
4770         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4771         rm -f $DIR/$tdir/funlink2
4772         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4773
4774         for (( i=0; i < 2; i++ )) ; do
4775                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4776                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4777                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4778                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4779
4780                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4781                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4782                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4783                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4784
4785                 cancel_lru_locks $OSC
4786                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4787         done
4788 }
4789 run_test 39b "mtime change on open, link, unlink, rename  ======"
4790
4791 # this should be set to past
4792 TEST_39_MTIME=`date -d "1 year ago" +%s`
4793
4794 # bug 11063
4795 test_39c() {
4796         touch $DIR1/$tfile
4797         sleep 2
4798         local mtime0=`stat -c %Y $DIR1/$tfile`
4799
4800         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4801         local mtime1=`stat -c %Y $DIR1/$tfile`
4802         [ "$mtime1" = $TEST_39_MTIME ] || \
4803                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4804
4805         local d1=`date +%s`
4806         echo hello >> $DIR1/$tfile
4807         local d2=`date +%s`
4808         local mtime2=`stat -c %Y $DIR1/$tfile`
4809         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4810                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4811
4812         mv $DIR1/$tfile $DIR1/$tfile-1
4813
4814         for (( i=0; i < 2; i++ )) ; do
4815                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4816                 [ "$mtime2" = "$mtime3" ] || \
4817                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4818
4819                 cancel_lru_locks $OSC
4820                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4821         done
4822 }
4823 run_test 39c "mtime change on rename ==========================="
4824
4825 # bug 21114
4826 test_39d() {
4827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4828
4829         touch $DIR1/$tfile
4830         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4831
4832         for (( i=0; i < 2; i++ )) ; do
4833                 local mtime=`stat -c %Y $DIR1/$tfile`
4834                 [ $mtime = $TEST_39_MTIME ] || \
4835                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4836
4837                 cancel_lru_locks $OSC
4838                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4839         done
4840 }
4841 run_test 39d "create, utime, stat =============================="
4842
4843 # bug 21114
4844 test_39e() {
4845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4846
4847         touch $DIR1/$tfile
4848         local mtime1=`stat -c %Y $DIR1/$tfile`
4849
4850         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4851
4852         for (( i=0; i < 2; i++ )) ; do
4853                 local mtime2=`stat -c %Y $DIR1/$tfile`
4854                 [ $mtime2 = $TEST_39_MTIME ] || \
4855                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4856
4857                 cancel_lru_locks $OSC
4858                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4859         done
4860 }
4861 run_test 39e "create, stat, utime, stat ========================"
4862
4863 # bug 21114
4864 test_39f() {
4865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4866
4867         touch $DIR1/$tfile
4868         mtime1=`stat -c %Y $DIR1/$tfile`
4869
4870         sleep 2
4871         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4872
4873         for (( i=0; i < 2; i++ )) ; do
4874                 local mtime2=`stat -c %Y $DIR1/$tfile`
4875                 [ $mtime2 = $TEST_39_MTIME ] || \
4876                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4877
4878                 cancel_lru_locks $OSC
4879                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4880         done
4881 }
4882 run_test 39f "create, stat, sleep, utime, stat ================="
4883
4884 # bug 11063
4885 test_39g() {
4886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4887
4888         echo hello >> $DIR1/$tfile
4889         local mtime1=`stat -c %Y $DIR1/$tfile`
4890
4891         sleep 2
4892         chmod o+r $DIR1/$tfile
4893
4894         for (( i=0; i < 2; i++ )) ; do
4895                 local mtime2=`stat -c %Y $DIR1/$tfile`
4896                 [ "$mtime1" = "$mtime2" ] || \
4897                         error "lost mtime: $mtime2, should be $mtime1"
4898
4899                 cancel_lru_locks $OSC
4900                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4901         done
4902 }
4903 run_test 39g "write, chmod, stat ==============================="
4904
4905 # bug 11063
4906 test_39h() {
4907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4908
4909         touch $DIR1/$tfile
4910         sleep 1
4911
4912         local d1=`date`
4913         echo hello >> $DIR1/$tfile
4914         local mtime1=`stat -c %Y $DIR1/$tfile`
4915
4916         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4917         local d2=`date`
4918         if [ "$d1" != "$d2" ]; then
4919                 echo "write and touch not within one second"
4920         else
4921                 for (( i=0; i < 2; i++ )) ; do
4922                         local mtime2=`stat -c %Y $DIR1/$tfile`
4923                         [ "$mtime2" = $TEST_39_MTIME ] || \
4924                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4925
4926                         cancel_lru_locks $OSC
4927                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4928                 done
4929         fi
4930 }
4931 run_test 39h "write, utime within one second, stat ============="
4932
4933 test_39i() {
4934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4935
4936         touch $DIR1/$tfile
4937         sleep 1
4938
4939         echo hello >> $DIR1/$tfile
4940         local mtime1=`stat -c %Y $DIR1/$tfile`
4941
4942         mv $DIR1/$tfile $DIR1/$tfile-1
4943
4944         for (( i=0; i < 2; i++ )) ; do
4945                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4946
4947                 [ "$mtime1" = "$mtime2" ] || \
4948                         error "lost mtime: $mtime2, should be $mtime1"
4949
4950                 cancel_lru_locks $OSC
4951                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4952         done
4953 }
4954 run_test 39i "write, rename, stat =============================="
4955
4956 test_39j() {
4957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4958
4959         start_full_debug_logging
4960         touch $DIR1/$tfile
4961         sleep 1
4962
4963         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4964         lctl set_param fail_loc=0x80000412
4965         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4966                 error "multiop failed"
4967         local multipid=$!
4968         local mtime1=`stat -c %Y $DIR1/$tfile`
4969
4970         mv $DIR1/$tfile $DIR1/$tfile-1
4971
4972         kill -USR1 $multipid
4973         wait $multipid || error "multiop close failed"
4974
4975         for (( i=0; i < 2; i++ )) ; do
4976                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4977                 [ "$mtime1" = "$mtime2" ] ||
4978                         error "mtime is lost on close: $mtime2, " \
4979                               "should be $mtime1"
4980
4981                 cancel_lru_locks
4982                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4983         done
4984         lctl set_param fail_loc=0
4985         stop_full_debug_logging
4986 }
4987 run_test 39j "write, rename, close, stat ======================="
4988
4989 test_39k() {
4990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4991
4992         touch $DIR1/$tfile
4993         sleep 1
4994
4995         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4996         local multipid=$!
4997         local mtime1=`stat -c %Y $DIR1/$tfile`
4998
4999         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5000
5001         kill -USR1 $multipid
5002         wait $multipid || error "multiop close failed"
5003
5004         for (( i=0; i < 2; i++ )) ; do
5005                 local mtime2=`stat -c %Y $DIR1/$tfile`
5006
5007                 [ "$mtime2" = $TEST_39_MTIME ] || \
5008                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5009
5010                 cancel_lru_locks
5011                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5012         done
5013 }
5014 run_test 39k "write, utime, close, stat ========================"
5015
5016 # this should be set to future
5017 TEST_39_ATIME=`date -d "1 year" +%s`
5018
5019 test_39l() {
5020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5021         remote_mds_nodsh && skip "remote MDS with nodsh"
5022
5023         local atime_diff=$(do_facet $SINGLEMDS \
5024                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5025         rm -rf $DIR/$tdir
5026         mkdir_on_mdt0 $DIR/$tdir
5027
5028         # test setting directory atime to future
5029         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5030         local atime=$(stat -c %X $DIR/$tdir)
5031         [ "$atime" = $TEST_39_ATIME ] ||
5032                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5033
5034         # test setting directory atime from future to now
5035         local now=$(date +%s)
5036         touch -a -d @$now $DIR/$tdir
5037
5038         atime=$(stat -c %X $DIR/$tdir)
5039         [ "$atime" -eq "$now"  ] ||
5040                 error "atime is not updated from future: $atime, $now"
5041
5042         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5043         sleep 3
5044
5045         # test setting directory atime when now > dir atime + atime_diff
5046         local d1=$(date +%s)
5047         ls $DIR/$tdir
5048         local d2=$(date +%s)
5049         cancel_lru_locks mdc
5050         atime=$(stat -c %X $DIR/$tdir)
5051         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5052                 error "atime is not updated  : $atime, should be $d2"
5053
5054         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5055         sleep 3
5056
5057         # test not setting directory atime when now < dir atime + atime_diff
5058         ls $DIR/$tdir
5059         cancel_lru_locks mdc
5060         atime=$(stat -c %X $DIR/$tdir)
5061         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5062                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5063
5064         do_facet $SINGLEMDS \
5065                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5066 }
5067 run_test 39l "directory atime update ==========================="
5068
5069 test_39m() {
5070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5071
5072         touch $DIR1/$tfile
5073         sleep 2
5074         local far_past_mtime=$(date -d "May 29 1953" +%s)
5075         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5076
5077         touch -m -d @$far_past_mtime $DIR1/$tfile
5078         touch -a -d @$far_past_atime $DIR1/$tfile
5079
5080         for (( i=0; i < 2; i++ )) ; do
5081                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5082                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5083                         error "atime or mtime set incorrectly"
5084
5085                 cancel_lru_locks $OSC
5086                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5087         done
5088 }
5089 run_test 39m "test atime and mtime before 1970"
5090
5091 test_39n() { # LU-3832
5092         remote_mds_nodsh && skip "remote MDS with nodsh"
5093
5094         local atime_diff=$(do_facet $SINGLEMDS \
5095                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5096         local atime0
5097         local atime1
5098         local atime2
5099
5100         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5101
5102         rm -rf $DIR/$tfile
5103         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5104         atime0=$(stat -c %X $DIR/$tfile)
5105
5106         sleep 5
5107         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5108         atime1=$(stat -c %X $DIR/$tfile)
5109
5110         sleep 5
5111         cancel_lru_locks mdc
5112         cancel_lru_locks osc
5113         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5114         atime2=$(stat -c %X $DIR/$tfile)
5115
5116         do_facet $SINGLEMDS \
5117                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5118
5119         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5120         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5121 }
5122 run_test 39n "check that O_NOATIME is honored"
5123
5124 test_39o() {
5125         TESTDIR=$DIR/$tdir/$tfile
5126         [ -e $TESTDIR ] && rm -rf $TESTDIR
5127         mkdir -p $TESTDIR
5128         cd $TESTDIR
5129         links1=2
5130         ls
5131         mkdir a b
5132         ls
5133         links2=$(stat -c %h .)
5134         [ $(($links1 + 2)) != $links2 ] &&
5135                 error "wrong links count $(($links1 + 2)) != $links2"
5136         rmdir b
5137         links3=$(stat -c %h .)
5138         [ $(($links1 + 1)) != $links3 ] &&
5139                 error "wrong links count $links1 != $links3"
5140         return 0
5141 }
5142 run_test 39o "directory cached attributes updated after create"
5143
5144 test_39p() {
5145         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5146
5147         local MDTIDX=1
5148         TESTDIR=$DIR/$tdir/$tdir
5149         [ -e $TESTDIR ] && rm -rf $TESTDIR
5150         test_mkdir -p $TESTDIR
5151         cd $TESTDIR
5152         links1=2
5153         ls
5154         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5155         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5156         ls
5157         links2=$(stat -c %h .)
5158         [ $(($links1 + 2)) != $links2 ] &&
5159                 error "wrong links count $(($links1 + 2)) != $links2"
5160         rmdir remote_dir2
5161         links3=$(stat -c %h .)
5162         [ $(($links1 + 1)) != $links3 ] &&
5163                 error "wrong links count $links1 != $links3"
5164         return 0
5165 }
5166 run_test 39p "remote directory cached attributes updated after create ========"
5167
5168 test_39r() {
5169         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5170                 skip "no atime update on old OST"
5171         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5172                 skip_env "ldiskfs only test"
5173         fi
5174
5175         local saved_adiff
5176         saved_adiff=$(do_facet ost1 \
5177                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5178         stack_trap "do_facet ost1 \
5179                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5180
5181         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5182
5183         $LFS setstripe -i 0 $DIR/$tfile
5184         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5185                 error "can't write initial file"
5186         cancel_lru_locks osc
5187
5188         # exceed atime_diff and access file
5189         sleep 10
5190         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5191                 error "can't udpate atime"
5192
5193         local atime_cli=$(stat -c %X $DIR/$tfile)
5194         echo "client atime: $atime_cli"
5195         # allow atime update to be written to device
5196         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5197         sleep 5
5198
5199         local ostdev=$(ostdevname 1)
5200         local fid=($(lfs getstripe -y $DIR/$tfile |
5201                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5202         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5203         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5204
5205         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5206         local atime_ost=$(do_facet ost1 "$cmd" |&
5207                           awk -F'[: ]' '/atime:/ { print $4 }')
5208         (( atime_cli == atime_ost )) ||
5209                 error "atime on client $atime_cli != ost $atime_ost"
5210 }
5211 run_test 39r "lazy atime update on OST"
5212
5213 test_39q() { # LU-8041
5214         local testdir=$DIR/$tdir
5215         mkdir -p $testdir
5216         multiop_bg_pause $testdir D_c || error "multiop failed"
5217         local multipid=$!
5218         cancel_lru_locks mdc
5219         kill -USR1 $multipid
5220         local atime=$(stat -c %X $testdir)
5221         [ "$atime" -ne 0 ] || error "atime is zero"
5222 }
5223 run_test 39q "close won't zero out atime"
5224
5225 test_40() {
5226         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5227         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5228                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5229         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5230                 error "$tfile is not 4096 bytes in size"
5231 }
5232 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5233
5234 test_41() {
5235         # bug 1553
5236         small_write $DIR/f41 18
5237 }
5238 run_test 41 "test small file write + fstat ====================="
5239
5240 count_ost_writes() {
5241         lctl get_param -n ${OSC}.*.stats |
5242                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5243                         END { printf("%0.0f", writes) }'
5244 }
5245
5246 # decent default
5247 WRITEBACK_SAVE=500
5248 DIRTY_RATIO_SAVE=40
5249 MAX_DIRTY_RATIO=50
5250 BG_DIRTY_RATIO_SAVE=10
5251 MAX_BG_DIRTY_RATIO=25
5252
5253 start_writeback() {
5254         trap 0
5255         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5256         # dirty_ratio, dirty_background_ratio
5257         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5258                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5259                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5260                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5261         else
5262                 # if file not here, we are a 2.4 kernel
5263                 kill -CONT `pidof kupdated`
5264         fi
5265 }
5266
5267 stop_writeback() {
5268         # setup the trap first, so someone cannot exit the test at the
5269         # exact wrong time and mess up a machine
5270         trap start_writeback EXIT
5271         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5272         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5273                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5274                 sysctl -w vm.dirty_writeback_centisecs=0
5275                 sysctl -w vm.dirty_writeback_centisecs=0
5276                 # save and increase /proc/sys/vm/dirty_ratio
5277                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5278                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5279                 # save and increase /proc/sys/vm/dirty_background_ratio
5280                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5281                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5282         else
5283                 # if file not here, we are a 2.4 kernel
5284                 kill -STOP `pidof kupdated`
5285         fi
5286 }
5287
5288 # ensure that all stripes have some grant before we test client-side cache
5289 setup_test42() {
5290         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5291                 dd if=/dev/zero of=$i bs=4k count=1
5292                 rm $i
5293         done
5294 }
5295
5296 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5297 # file truncation, and file removal.
5298 test_42a() {
5299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5300
5301         setup_test42
5302         cancel_lru_locks $OSC
5303         stop_writeback
5304         sync; sleep 1; sync # just to be safe
5305         BEFOREWRITES=`count_ost_writes`
5306         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5307         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5308         AFTERWRITES=`count_ost_writes`
5309         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5310                 error "$BEFOREWRITES < $AFTERWRITES"
5311         start_writeback
5312 }
5313 run_test 42a "ensure that we don't flush on close"
5314
5315 test_42b() {
5316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5317
5318         setup_test42
5319         cancel_lru_locks $OSC
5320         stop_writeback
5321         sync
5322         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5323         BEFOREWRITES=$(count_ost_writes)
5324         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5325         AFTERWRITES=$(count_ost_writes)
5326         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5327                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5328         fi
5329         BEFOREWRITES=$(count_ost_writes)
5330         sync || error "sync: $?"
5331         AFTERWRITES=$(count_ost_writes)
5332         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5333                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5334         fi
5335         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5336         start_writeback
5337         return 0
5338 }
5339 run_test 42b "test destroy of file with cached dirty data ======"
5340
5341 # if these tests just want to test the effect of truncation,
5342 # they have to be very careful.  consider:
5343 # - the first open gets a {0,EOF}PR lock
5344 # - the first write conflicts and gets a {0, count-1}PW
5345 # - the rest of the writes are under {count,EOF}PW
5346 # - the open for truncate tries to match a {0,EOF}PR
5347 #   for the filesize and cancels the PWs.
5348 # any number of fixes (don't get {0,EOF} on open, match
5349 # composite locks, do smarter file size management) fix
5350 # this, but for now we want these tests to verify that
5351 # the cancellation with truncate intent works, so we
5352 # start the file with a full-file pw lock to match against
5353 # until the truncate.
5354 trunc_test() {
5355         test=$1
5356         file=$DIR/$test
5357         offset=$2
5358         cancel_lru_locks $OSC
5359         stop_writeback
5360         # prime the file with 0,EOF PW to match
5361         touch $file
5362         $TRUNCATE $file 0
5363         sync; sync
5364         # now the real test..
5365         dd if=/dev/zero of=$file bs=1024 count=100
5366         BEFOREWRITES=`count_ost_writes`
5367         $TRUNCATE $file $offset
5368         cancel_lru_locks $OSC
5369         AFTERWRITES=`count_ost_writes`
5370         start_writeback
5371 }
5372
5373 test_42c() {
5374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5375
5376         trunc_test 42c 1024
5377         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5378                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5379         rm $file
5380 }
5381 run_test 42c "test partial truncate of file with cached dirty data"
5382
5383 test_42d() {
5384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5385
5386         trunc_test 42d 0
5387         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5388                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5389         rm $file
5390 }
5391 run_test 42d "test complete truncate of file with cached dirty data"
5392
5393 test_42e() { # bug22074
5394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5395
5396         local TDIR=$DIR/${tdir}e
5397         local pages=16 # hardcoded 16 pages, don't change it.
5398         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5399         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5400         local max_dirty_mb
5401         local warmup_files
5402
5403         test_mkdir $DIR/${tdir}e
5404         $LFS setstripe -c 1 $TDIR
5405         createmany -o $TDIR/f $files
5406
5407         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5408
5409         # we assume that with $OSTCOUNT files, at least one of them will
5410         # be allocated on OST0.
5411         warmup_files=$((OSTCOUNT * max_dirty_mb))
5412         createmany -o $TDIR/w $warmup_files
5413
5414         # write a large amount of data into one file and sync, to get good
5415         # avail_grant number from OST.
5416         for ((i=0; i<$warmup_files; i++)); do
5417                 idx=$($LFS getstripe -i $TDIR/w$i)
5418                 [ $idx -ne 0 ] && continue
5419                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5420                 break
5421         done
5422         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5423         sync
5424         $LCTL get_param $proc_osc0/cur_dirty_bytes
5425         $LCTL get_param $proc_osc0/cur_grant_bytes
5426
5427         # create as much dirty pages as we can while not to trigger the actual
5428         # RPCs directly. but depends on the env, VFS may trigger flush during this
5429         # period, hopefully we are good.
5430         for ((i=0; i<$warmup_files; i++)); do
5431                 idx=$($LFS getstripe -i $TDIR/w$i)
5432                 [ $idx -ne 0 ] && continue
5433                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5434         done
5435         $LCTL get_param $proc_osc0/cur_dirty_bytes
5436         $LCTL get_param $proc_osc0/cur_grant_bytes
5437
5438         # perform the real test
5439         $LCTL set_param $proc_osc0/rpc_stats 0
5440         for ((;i<$files; i++)); do
5441                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5442                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5443         done
5444         sync
5445         $LCTL get_param $proc_osc0/rpc_stats
5446
5447         local percent=0
5448         local have_ppr=false
5449         $LCTL get_param $proc_osc0/rpc_stats |
5450                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5451                         # skip lines until we are at the RPC histogram data
5452                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5453                         $have_ppr || continue
5454
5455                         # we only want the percent stat for < 16 pages
5456                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5457
5458                         percent=$((percent + WPCT))
5459                         if [[ $percent -gt 15 ]]; then
5460                                 error "less than 16-pages write RPCs" \
5461                                       "$percent% > 15%"
5462                                 break
5463                         fi
5464                 done
5465         rm -rf $TDIR
5466 }
5467 run_test 42e "verify sub-RPC writes are not done synchronously"
5468
5469 test_43A() { # was test_43
5470         test_mkdir $DIR/$tdir
5471         cp -p /bin/ls $DIR/$tdir/$tfile
5472         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5473         pid=$!
5474         # give multiop a chance to open
5475         sleep 1
5476
5477         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5478         kill -USR1 $pid
5479         # Wait for multiop to exit
5480         wait $pid
5481 }
5482 run_test 43A "execution of file opened for write should return -ETXTBSY"
5483
5484 test_43a() {
5485         test_mkdir $DIR/$tdir
5486         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5487         $DIR/$tdir/sleep 60 &
5488         SLEEP_PID=$!
5489         # Make sure exec of $tdir/sleep wins race with truncate
5490         sleep 1
5491         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5492         kill $SLEEP_PID
5493 }
5494 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5495
5496 test_43b() {
5497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5498
5499         test_mkdir $DIR/$tdir
5500         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5501         $DIR/$tdir/sleep 60 &
5502         SLEEP_PID=$!
5503         # Make sure exec of $tdir/sleep wins race with truncate
5504         sleep 1
5505         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5506         kill $SLEEP_PID
5507 }
5508 run_test 43b "truncate of file being executed should return -ETXTBSY"
5509
5510 test_43c() {
5511         local testdir="$DIR/$tdir"
5512         test_mkdir $testdir
5513         cp $SHELL $testdir/
5514         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5515                 ( cd $testdir && md5sum -c )
5516 }
5517 run_test 43c "md5sum of copy into lustre"
5518
5519 test_44A() { # was test_44
5520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5521
5522         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5523         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5524 }
5525 run_test 44A "zero length read from a sparse stripe"
5526
5527 test_44a() {
5528         local nstripe=$($LFS getstripe -c -d $DIR)
5529         [ -z "$nstripe" ] && skip "can't get stripe info"
5530         [[ $nstripe -gt $OSTCOUNT ]] &&
5531                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5532
5533         local stride=$($LFS getstripe -S -d $DIR)
5534         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5535                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5536         fi
5537
5538         OFFSETS="0 $((stride/2)) $((stride-1))"
5539         for offset in $OFFSETS; do
5540                 for i in $(seq 0 $((nstripe-1))); do
5541                         local GLOBALOFFSETS=""
5542                         # size in Bytes
5543                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5544                         local myfn=$DIR/d44a-$size
5545                         echo "--------writing $myfn at $size"
5546                         ll_sparseness_write $myfn $size ||
5547                                 error "ll_sparseness_write"
5548                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5549                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5550                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5551
5552                         for j in $(seq 0 $((nstripe-1))); do
5553                                 # size in Bytes
5554                                 size=$((((j + $nstripe )*$stride + $offset)))
5555                                 ll_sparseness_write $myfn $size ||
5556                                         error "ll_sparseness_write"
5557                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5558                         done
5559                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5560                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5561                         rm -f $myfn
5562                 done
5563         done
5564 }
5565 run_test 44a "test sparse pwrite ==============================="
5566
5567 dirty_osc_total() {
5568         tot=0
5569         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5570                 tot=$(($tot + $d))
5571         done
5572         echo $tot
5573 }
5574 do_dirty_record() {
5575         before=`dirty_osc_total`
5576         echo executing "\"$*\""
5577         eval $*
5578         after=`dirty_osc_total`
5579         echo before $before, after $after
5580 }
5581 test_45() {
5582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5583
5584         f="$DIR/f45"
5585         # Obtain grants from OST if it supports it
5586         echo blah > ${f}_grant
5587         stop_writeback
5588         sync
5589         do_dirty_record "echo blah > $f"
5590         [[ $before -eq $after ]] && error "write wasn't cached"
5591         do_dirty_record "> $f"
5592         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5593         do_dirty_record "echo blah > $f"
5594         [[ $before -eq $after ]] && error "write wasn't cached"
5595         do_dirty_record "sync"
5596         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5597         do_dirty_record "echo blah > $f"
5598         [[ $before -eq $after ]] && error "write wasn't cached"
5599         do_dirty_record "cancel_lru_locks osc"
5600         [[ $before -gt $after ]] ||
5601                 error "lock cancellation didn't lower dirty count"
5602         start_writeback
5603 }
5604 run_test 45 "osc io page accounting ============================"
5605
5606 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5607 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5608 # objects offset and an assert hit when an rpc was built with 1023's mapped
5609 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5610 test_46() {
5611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5612
5613         f="$DIR/f46"
5614         stop_writeback
5615         sync
5616         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5617         sync
5618         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5619         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5620         sync
5621         start_writeback
5622 }
5623 run_test 46 "dirtying a previously written page ================"
5624
5625 # test_47 is removed "Device nodes check" is moved to test_28
5626
5627 test_48a() { # bug 2399
5628         [ "$mds1_FSTYPE" = "zfs" ] &&
5629         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5630                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5631
5632         test_mkdir $DIR/$tdir
5633         cd $DIR/$tdir
5634         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5635         test_mkdir $DIR/$tdir
5636         touch foo || error "'touch foo' failed after recreating cwd"
5637         test_mkdir bar
5638         touch .foo || error "'touch .foo' failed after recreating cwd"
5639         test_mkdir .bar
5640         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5641         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5642         cd . || error "'cd .' failed after recreating cwd"
5643         mkdir . && error "'mkdir .' worked after recreating cwd"
5644         rmdir . && error "'rmdir .' worked after recreating cwd"
5645         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5646         cd .. || error "'cd ..' failed after recreating cwd"
5647 }
5648 run_test 48a "Access renamed working dir (should return errors)="
5649
5650 test_48b() { # bug 2399
5651         rm -rf $DIR/$tdir
5652         test_mkdir $DIR/$tdir
5653         cd $DIR/$tdir
5654         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5655         touch foo && error "'touch foo' worked after removing cwd"
5656         mkdir foo && error "'mkdir foo' worked after removing cwd"
5657         touch .foo && error "'touch .foo' worked after removing cwd"
5658         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5659         ls . > /dev/null && error "'ls .' worked after removing cwd"
5660         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5661         mkdir . && error "'mkdir .' worked after removing cwd"
5662         rmdir . && error "'rmdir .' worked after removing cwd"
5663         ln -s . foo && error "'ln -s .' worked after removing cwd"
5664         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5665 }
5666 run_test 48b "Access removed working dir (should return errors)="
5667
5668 test_48c() { # bug 2350
5669         #lctl set_param debug=-1
5670         #set -vx
5671         rm -rf $DIR/$tdir
5672         test_mkdir -p $DIR/$tdir/dir
5673         cd $DIR/$tdir/dir
5674         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5675         $TRACE touch foo && error "touch foo worked after removing cwd"
5676         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5677         touch .foo && error "touch .foo worked after removing cwd"
5678         mkdir .foo && error "mkdir .foo worked after removing cwd"
5679         $TRACE ls . && error "'ls .' worked after removing cwd"
5680         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5681         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5682         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5683         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5684         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5685 }
5686 run_test 48c "Access removed working subdir (should return errors)"
5687
5688 test_48d() { # bug 2350
5689         #lctl set_param debug=-1
5690         #set -vx
5691         rm -rf $DIR/$tdir
5692         test_mkdir -p $DIR/$tdir/dir
5693         cd $DIR/$tdir/dir
5694         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5695         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5696         $TRACE touch foo && error "'touch foo' worked after removing parent"
5697         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5698         touch .foo && error "'touch .foo' worked after removing parent"
5699         mkdir .foo && error "mkdir .foo worked after removing parent"
5700         $TRACE ls . && error "'ls .' worked after removing parent"
5701         $TRACE ls .. && error "'ls ..' worked after removing parent"
5702         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5703         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5704         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5705         true
5706 }
5707 run_test 48d "Access removed parent subdir (should return errors)"
5708
5709 test_48e() { # bug 4134
5710         #lctl set_param debug=-1
5711         #set -vx
5712         rm -rf $DIR/$tdir
5713         test_mkdir -p $DIR/$tdir/dir
5714         cd $DIR/$tdir/dir
5715         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5716         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5717         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5718         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5719         # On a buggy kernel addition of "touch foo" after cd .. will
5720         # produce kernel oops in lookup_hash_it
5721         touch ../foo && error "'cd ..' worked after recreate parent"
5722         cd $DIR
5723         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5724 }
5725 run_test 48e "Access to recreated parent subdir (should return errors)"
5726
5727 test_48f() {
5728         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5729                 skip "need MDS >= 2.13.55"
5730         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5731         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5732                 skip "needs different host for mdt1 mdt2"
5733         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5734
5735         $LFS mkdir -i0 $DIR/$tdir
5736         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5737
5738         for d in sub1 sub2 sub3; do
5739                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5740                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5741                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5742         done
5743
5744         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5745 }
5746 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5747
5748 test_49() { # LU-1030
5749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5750         remote_ost_nodsh && skip "remote OST with nodsh"
5751
5752         # get ost1 size - $FSNAME-OST0000
5753         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5754                 awk '{ print $4 }')
5755         # write 800M at maximum
5756         [[ $ost1_size -lt 2 ]] && ost1_size=2
5757         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5758
5759         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5760         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5761         local dd_pid=$!
5762
5763         # change max_pages_per_rpc while writing the file
5764         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5765         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5766         # loop until dd process exits
5767         while ps ax -opid | grep -wq $dd_pid; do
5768                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5769                 sleep $((RANDOM % 5 + 1))
5770         done
5771         # restore original max_pages_per_rpc
5772         $LCTL set_param $osc1_mppc=$orig_mppc
5773         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5774 }
5775 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5776
5777 test_50() {
5778         # bug 1485
5779         test_mkdir $DIR/$tdir
5780         cd $DIR/$tdir
5781         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5782 }
5783 run_test 50 "special situations: /proc symlinks  ==============="
5784
5785 test_51a() {    # was test_51
5786         # bug 1516 - create an empty entry right after ".." then split dir
5787         test_mkdir -c1 $DIR/$tdir
5788         touch $DIR/$tdir/foo
5789         $MCREATE $DIR/$tdir/bar
5790         rm $DIR/$tdir/foo
5791         createmany -m $DIR/$tdir/longfile 201
5792         FNUM=202
5793         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5794                 $MCREATE $DIR/$tdir/longfile$FNUM
5795                 FNUM=$(($FNUM + 1))
5796                 echo -n "+"
5797         done
5798         echo
5799         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5800 }
5801 run_test 51a "special situations: split htree with empty entry =="
5802
5803 cleanup_print_lfs_df () {
5804         trap 0
5805         $LFS df
5806         $LFS df -i
5807 }
5808
5809 test_51b() {
5810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5811
5812         local dir=$DIR/$tdir
5813         local nrdirs=$((65536 + 100))
5814
5815         # cleanup the directory
5816         rm -fr $dir
5817
5818         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5819
5820         $LFS df
5821         $LFS df -i
5822         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5823         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5824         [[ $numfree -lt $nrdirs ]] &&
5825                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5826
5827         # need to check free space for the directories as well
5828         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5829         numfree=$(( blkfree / $(fs_inode_ksize) ))
5830         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5831
5832         trap cleanup_print_lfs_df EXIT
5833
5834         # create files
5835         createmany -d $dir/d $nrdirs || {
5836                 unlinkmany $dir/d $nrdirs
5837                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5838         }
5839
5840         # really created :
5841         nrdirs=$(ls -U $dir | wc -l)
5842
5843         # unlink all but 100 subdirectories, then check it still works
5844         local left=100
5845         local delete=$((nrdirs - left))
5846
5847         $LFS df
5848         $LFS df -i
5849
5850         # for ldiskfs the nlink count should be 1, but this is OSD specific
5851         # and so this is listed for informational purposes only
5852         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5853         unlinkmany -d $dir/d $delete ||
5854                 error "unlink of first $delete subdirs failed"
5855
5856         echo "nlink between: $(stat -c %h $dir)"
5857         local found=$(ls -U $dir | wc -l)
5858         [ $found -ne $left ] &&
5859                 error "can't find subdirs: found only $found, expected $left"
5860
5861         unlinkmany -d $dir/d $delete $left ||
5862                 error "unlink of second $left subdirs failed"
5863         # regardless of whether the backing filesystem tracks nlink accurately
5864         # or not, the nlink count shouldn't be more than "." and ".." here
5865         local after=$(stat -c %h $dir)
5866         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5867                 echo "nlink after: $after"
5868
5869         cleanup_print_lfs_df
5870 }
5871 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5872
5873 test_51d_sub() {
5874         local stripecount=$1
5875         local nfiles=$((200 * $OSTCOUNT))
5876
5877         log "create files with stripecount=$stripecount"
5878         $LFS setstripe -C $stripecount $DIR/$tdir
5879         createmany -o $DIR/$tdir/t- $nfiles
5880         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5881         for ((n = 0; n < $OSTCOUNT; n++)); do
5882                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5883                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5884                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5885                             '($1 == '$n') { objs += 1 } \
5886                             END { printf("%0.0f", objs) }')
5887                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5888         done
5889         unlinkmany $DIR/$tdir/t- $nfiles
5890         rm  -f $TMP/$tfile
5891
5892         local nlast
5893         local min=4
5894         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5895
5896         # For some combinations of stripecount and OSTCOUNT current code
5897         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5898         # than others. Rather than skipping this test entirely, check that
5899         # and keep testing to ensure imbalance does not get worse. LU-15282
5900         (( (OSTCOUNT == 6 && stripecount == 4) ||
5901            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5902            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5903         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5904                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5905                         { $LFS df && $LFS df -i &&
5906                         error "OST $n has fewer objects vs. OST $nlast " \
5907                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5908                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5909                         { $LFS df && $LFS df -i &&
5910                         error "OST $n has fewer objects vs. OST $nlast " \
5911                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5912
5913                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5914                         { $LFS df && $LFS df -i &&
5915                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5916                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5917                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5918                         { $LFS df && $LFS df -i &&
5919                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5920                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5921         done
5922 }
5923
5924 test_51d() {
5925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5926         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5927
5928         local stripecount
5929         local qos_old=$(do_facet mds1 \
5930                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5931
5932         do_nodes $(comma_list $(mdts_nodes)) \
5933                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5934         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5935                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5936
5937         test_mkdir $DIR/$tdir
5938
5939         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5940                 test_51d_sub $stripecount
5941         done
5942 }
5943 run_test 51d "check object distribution"
5944
5945 test_51e() {
5946         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5947                 skip_env "ldiskfs only test"
5948         fi
5949
5950         test_mkdir -c1 $DIR/$tdir
5951         test_mkdir -c1 $DIR/$tdir/d0
5952
5953         touch $DIR/$tdir/d0/foo
5954         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5955                 error "file exceed 65000 nlink limit!"
5956         unlinkmany $DIR/$tdir/d0/f- 65001
5957         return 0
5958 }
5959 run_test 51e "check file nlink limit"
5960
5961 test_51f() {
5962         test_mkdir $DIR/$tdir
5963
5964         local max=100000
5965         local ulimit_old=$(ulimit -n)
5966         local spare=20 # number of spare fd's for scripts/libraries, etc.
5967         local mdt=$($LFS getstripe -m $DIR/$tdir)
5968         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5969
5970         echo "MDT$mdt numfree=$numfree, max=$max"
5971         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5972         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5973                 while ! ulimit -n $((numfree + spare)); do
5974                         numfree=$((numfree * 3 / 4))
5975                 done
5976                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5977         else
5978                 echo "left ulimit at $ulimit_old"
5979         fi
5980
5981         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5982                 unlinkmany $DIR/$tdir/f $numfree
5983                 error "create+open $numfree files in $DIR/$tdir failed"
5984         }
5985         ulimit -n $ulimit_old
5986
5987         # if createmany exits at 120s there will be fewer than $numfree files
5988         unlinkmany $DIR/$tdir/f $numfree || true
5989 }
5990 run_test 51f "check many open files limit"
5991
5992 test_52a() {
5993         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5994         test_mkdir $DIR/$tdir
5995         touch $DIR/$tdir/foo
5996         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5997         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5998         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5999         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6000         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6001                                         error "link worked"
6002         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6003         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6004         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6005                                                      error "lsattr"
6006         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6007         cp -r $DIR/$tdir $TMP/
6008         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6009 }
6010 run_test 52a "append-only flag test (should return errors)"
6011
6012 test_52b() {
6013         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6014         test_mkdir $DIR/$tdir
6015         touch $DIR/$tdir/foo
6016         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6017         cat test > $DIR/$tdir/foo && error "cat test worked"
6018         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6019         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6020         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6021                                         error "link worked"
6022         echo foo >> $DIR/$tdir/foo && error "echo worked"
6023         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6024         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6025         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6026         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6027                                                         error "lsattr"
6028         chattr -i $DIR/$tdir/foo || error "chattr failed"
6029
6030         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6031 }
6032 run_test 52b "immutable flag test (should return errors) ======="
6033
6034 test_53() {
6035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6036         remote_mds_nodsh && skip "remote MDS with nodsh"
6037         remote_ost_nodsh && skip "remote OST with nodsh"
6038
6039         local param
6040         local param_seq
6041         local ostname
6042         local mds_last
6043         local mds_last_seq
6044         local ost_last
6045         local ost_last_seq
6046         local ost_last_id
6047         local ostnum
6048         local node
6049         local found=false
6050         local support_last_seq=true
6051
6052         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6053                 support_last_seq=false
6054
6055         # only test MDT0000
6056         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6057         local value
6058         for value in $(do_facet $SINGLEMDS \
6059                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6060                 param=$(echo ${value[0]} | cut -d "=" -f1)
6061                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6062
6063                 if $support_last_seq; then
6064                         param_seq=$(echo $param |
6065                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6066                         mds_last_seq=$(do_facet $SINGLEMDS \
6067                                        $LCTL get_param -n $param_seq)
6068                 fi
6069                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6070
6071                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6072                 node=$(facet_active_host ost$((ostnum+1)))
6073                 param="obdfilter.$ostname.last_id"
6074                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6075                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6076                         ost_last_id=$ost_last
6077
6078                         if $support_last_seq; then
6079                                 ost_last_id=$(echo $ost_last |
6080                                               awk -F':' '{print $2}' |
6081                                               sed -e "s/^0x//g")
6082                                 ost_last_seq=$(echo $ost_last |
6083                                                awk -F':' '{print $1}')
6084                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6085                         fi
6086
6087                         if [[ $ost_last_id != $mds_last ]]; then
6088                                 error "$ost_last_id != $mds_last"
6089                         else
6090                                 found=true
6091                                 break
6092                         fi
6093                 done
6094         done
6095         $found || error "can not match last_seq/last_id for $mdtosc"
6096         return 0
6097 }
6098 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6099
6100 test_54a() {
6101         perl -MSocket -e ';' || skip "no Socket perl module installed"
6102
6103         $SOCKETSERVER $DIR/socket ||
6104                 error "$SOCKETSERVER $DIR/socket failed: $?"
6105         $SOCKETCLIENT $DIR/socket ||
6106                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6107         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6108 }
6109 run_test 54a "unix domain socket test =========================="
6110
6111 test_54b() {
6112         f="$DIR/f54b"
6113         mknod $f c 1 3
6114         chmod 0666 $f
6115         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6116 }
6117 run_test 54b "char device works in lustre ======================"
6118
6119 find_loop_dev() {
6120         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6121         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6122         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6123
6124         for i in $(seq 3 7); do
6125                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6126                 LOOPDEV=$LOOPBASE$i
6127                 LOOPNUM=$i
6128                 break
6129         done
6130 }
6131
6132 cleanup_54c() {
6133         local rc=0
6134         loopdev="$DIR/loop54c"
6135
6136         trap 0
6137         $UMOUNT $DIR/$tdir || rc=$?
6138         losetup -d $loopdev || true
6139         losetup -d $LOOPDEV || true
6140         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6141         return $rc
6142 }
6143
6144 test_54c() {
6145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6146
6147         loopdev="$DIR/loop54c"
6148
6149         find_loop_dev
6150         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6151         trap cleanup_54c EXIT
6152         mknod $loopdev b 7 $LOOPNUM
6153         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6154         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6155         losetup $loopdev $DIR/$tfile ||
6156                 error "can't set up $loopdev for $DIR/$tfile"
6157         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6158         test_mkdir $DIR/$tdir
6159         mount -t ext2 $loopdev $DIR/$tdir ||
6160                 error "error mounting $loopdev on $DIR/$tdir"
6161         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6162                 error "dd write"
6163         df $DIR/$tdir
6164         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6165                 error "dd read"
6166         cleanup_54c
6167 }
6168 run_test 54c "block device works in lustre ====================="
6169
6170 test_54d() {
6171         local pipe="$DIR/$tfile.pipe"
6172         local string="aaaaaa"
6173
6174         mknod $pipe p
6175         echo -n "$string" > $pipe &
6176         local result=$(cat $pipe)
6177         [[ "$result" == "$string" ]] || error "$result != $string"
6178 }
6179 run_test 54d "fifo device works in lustre ======================"
6180
6181 test_54e() {
6182         f="$DIR/f54e"
6183         string="aaaaaa"
6184         cp -aL /dev/console $f
6185         echo $string > $f || error "echo $string to $f failed"
6186 }
6187 run_test 54e "console/tty device works in lustre ======================"
6188
6189 test_56a() {
6190         local numfiles=3
6191         local numdirs=2
6192         local dir=$DIR/$tdir
6193
6194         rm -rf $dir
6195         test_mkdir -p $dir/dir
6196         for i in $(seq $numfiles); do
6197                 touch $dir/file$i
6198                 touch $dir/dir/file$i
6199         done
6200
6201         local numcomp=$($LFS getstripe --component-count $dir)
6202
6203         [[ $numcomp == 0 ]] && numcomp=1
6204
6205         # test lfs getstripe with --recursive
6206         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6207
6208         [[ $filenum -eq $((numfiles * 2)) ]] ||
6209                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6210         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6211         [[ $filenum -eq $numfiles ]] ||
6212                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6213         echo "$LFS getstripe showed obdidx or l_ost_idx"
6214
6215         # test lfs getstripe with file instead of dir
6216         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6217         [[ $filenum -eq 1 ]] ||
6218                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6219         echo "$LFS getstripe file1 passed"
6220
6221         #test lfs getstripe with --verbose
6222         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6223         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6224                 error "$LFS getstripe --verbose $dir: "\
6225                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6226         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6227                 error "$LFS getstripe $dir: showed lmm_magic"
6228
6229         #test lfs getstripe with -v prints lmm_fid
6230         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6231         local countfids=$((numdirs + numfiles * numcomp))
6232         [[ $filenum -eq $countfids ]] ||
6233                 error "$LFS getstripe -v $dir: "\
6234                       "got $filenum want $countfids lmm_fid"
6235         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6236                 error "$LFS getstripe $dir: showed lmm_fid by default"
6237         echo "$LFS getstripe --verbose passed"
6238
6239         #check for FID information
6240         local fid1=$($LFS getstripe --fid $dir/file1)
6241         local fid2=$($LFS getstripe --verbose $dir/file1 |
6242                      awk '/lmm_fid: / { print $2; exit; }')
6243         local fid3=$($LFS path2fid $dir/file1)
6244
6245         [ "$fid1" != "$fid2" ] &&
6246                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6247         [ "$fid1" != "$fid3" ] &&
6248                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6249         echo "$LFS getstripe --fid passed"
6250
6251         #test lfs getstripe with --obd
6252         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6253                 error "$LFS getstripe --obd wrong_uuid: should return error"
6254
6255         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6256
6257         local ostidx=1
6258         local obduuid=$(ostuuid_from_index $ostidx)
6259         local found=$($LFS getstripe -r --obd $obduuid $dir |
6260                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6261
6262         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6263         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6264                 ((filenum--))
6265         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6266                 ((filenum--))
6267
6268         [[ $found -eq $filenum ]] ||
6269                 error "$LFS getstripe --obd: found $found expect $filenum"
6270         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6271                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6272                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6273                 error "$LFS getstripe --obd: should not show file on other obd"
6274         echo "$LFS getstripe --obd passed"
6275 }
6276 run_test 56a "check $LFS getstripe"
6277
6278 test_56b() {
6279         local dir=$DIR/$tdir
6280         local numdirs=3
6281
6282         test_mkdir $dir
6283         for i in $(seq $numdirs); do
6284                 test_mkdir $dir/dir$i
6285         done
6286
6287         # test lfs getdirstripe default mode is non-recursion, which is
6288         # different from lfs getstripe
6289         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6290
6291         [[ $dircnt -eq 1 ]] ||
6292                 error "$LFS getdirstripe: found $dircnt, not 1"
6293         dircnt=$($LFS getdirstripe --recursive $dir |
6294                 grep -c lmv_stripe_count)
6295         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6296                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6297 }
6298 run_test 56b "check $LFS getdirstripe"
6299
6300 test_56c() {
6301         remote_ost_nodsh && skip "remote OST with nodsh"
6302
6303         local ost_idx=0
6304         local ost_name=$(ostname_from_index $ost_idx)
6305         local old_status=$(ost_dev_status $ost_idx)
6306         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6307
6308         [[ -z "$old_status" ]] ||
6309                 skip_env "OST $ost_name is in $old_status status"
6310
6311         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6312         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6313                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6314         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6315                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6316                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6317         fi
6318
6319         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6320                 error "$LFS df -v showing inactive devices"
6321         sleep_maxage
6322
6323         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6324
6325         [[ "$new_status" =~ "D" ]] ||
6326                 error "$ost_name status is '$new_status', missing 'D'"
6327         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6328                 [[ "$new_status" =~ "N" ]] ||
6329                         error "$ost_name status is '$new_status', missing 'N'"
6330         fi
6331         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6332                 [[ "$new_status" =~ "f" ]] ||
6333                         error "$ost_name status is '$new_status', missing 'f'"
6334         fi
6335
6336         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6337         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6338                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6339         [[ -z "$p" ]] && restore_lustre_params < $p || true
6340         sleep_maxage
6341
6342         new_status=$(ost_dev_status $ost_idx)
6343         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6344                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6345         # can't check 'f' as devices may actually be on flash
6346 }
6347 run_test 56c "check 'lfs df' showing device status"
6348
6349 test_56d() {
6350         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6351         local osts=$($LFS df -v $MOUNT | grep -c OST)
6352
6353         $LFS df $MOUNT
6354
6355         (( mdts == MDSCOUNT )) ||
6356                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6357         (( osts == OSTCOUNT )) ||
6358                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6359 }
6360 run_test 56d "'lfs df -v' prints only configured devices"
6361
6362 test_56e() {
6363         err_enoent=2 # No such file or directory
6364         err_eopnotsupp=95 # Operation not supported
6365
6366         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6367         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6368
6369         # Check for handling of path not exists
6370         output=$($LFS df $enoent_mnt 2>&1)
6371         ret=$?
6372
6373         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6374         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6375                 error "expect failure $err_enoent, not $ret"
6376
6377         # Check for handling of non-Lustre FS
6378         output=$($LFS df $notsup_mnt)
6379         ret=$?
6380
6381         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6382         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6383                 error "expect success $err_eopnotsupp, not $ret"
6384
6385         # Check for multiple LustreFS argument
6386         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6387         ret=$?
6388
6389         [[ $output -eq 3 && $ret -eq 0 ]] ||
6390                 error "expect success 3, not $output, rc = $ret"
6391
6392         # Check for correct non-Lustre FS handling among multiple
6393         # LustreFS argument
6394         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6395                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6396         ret=$?
6397
6398         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6399                 error "expect success 2, not $output, rc = $ret"
6400 }
6401 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6402
6403 NUMFILES=3
6404 NUMDIRS=3
6405 setup_56() {
6406         local local_tdir="$1"
6407         local local_numfiles="$2"
6408         local local_numdirs="$3"
6409         local dir_params="$4"
6410         local dir_stripe_params="$5"
6411
6412         if [ ! -d "$local_tdir" ] ; then
6413                 test_mkdir -p $dir_stripe_params $local_tdir
6414                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6415                 for i in $(seq $local_numfiles) ; do
6416                         touch $local_tdir/file$i
6417                 done
6418                 for i in $(seq $local_numdirs) ; do
6419                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6420                         for j in $(seq $local_numfiles) ; do
6421                                 touch $local_tdir/dir$i/file$j
6422                         done
6423                 done
6424         fi
6425 }
6426
6427 setup_56_special() {
6428         local local_tdir=$1
6429         local local_numfiles=$2
6430         local local_numdirs=$3
6431
6432         setup_56 $local_tdir $local_numfiles $local_numdirs
6433
6434         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6435                 for i in $(seq $local_numfiles) ; do
6436                         mknod $local_tdir/loop${i}b b 7 $i
6437                         mknod $local_tdir/null${i}c c 1 3
6438                         ln -s $local_tdir/file1 $local_tdir/link${i}
6439                 done
6440                 for i in $(seq $local_numdirs) ; do
6441                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6442                         mknod $local_tdir/dir$i/null${i}c c 1 3
6443                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6444                 done
6445         fi
6446 }
6447
6448 test_56g() {
6449         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6450         local expected=$(($NUMDIRS + 2))
6451
6452         setup_56 $dir $NUMFILES $NUMDIRS
6453
6454         # test lfs find with -name
6455         for i in $(seq $NUMFILES) ; do
6456                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6457
6458                 [ $nums -eq $expected ] ||
6459                         error "lfs find -name '*$i' $dir wrong: "\
6460                               "found $nums, expected $expected"
6461         done
6462 }
6463 run_test 56g "check lfs find -name"
6464
6465 test_56h() {
6466         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6467         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6468
6469         setup_56 $dir $NUMFILES $NUMDIRS
6470
6471         # test lfs find with ! -name
6472         for i in $(seq $NUMFILES) ; do
6473                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6474
6475                 [ $nums -eq $expected ] ||
6476                         error "lfs find ! -name '*$i' $dir wrong: "\
6477                               "found $nums, expected $expected"
6478         done
6479 }
6480 run_test 56h "check lfs find ! -name"
6481
6482 test_56i() {
6483         local dir=$DIR/$tdir
6484
6485         test_mkdir $dir
6486
6487         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6488         local out=$($cmd)
6489
6490         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6491 }
6492 run_test 56i "check 'lfs find -ost UUID' skips directories"
6493
6494 test_56j() {
6495         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6496
6497         setup_56_special $dir $NUMFILES $NUMDIRS
6498
6499         local expected=$((NUMDIRS + 1))
6500         local cmd="$LFS find -type d $dir"
6501         local nums=$($cmd | wc -l)
6502
6503         [ $nums -eq $expected ] ||
6504                 error "'$cmd' wrong: found $nums, expected $expected"
6505 }
6506 run_test 56j "check lfs find -type d"
6507
6508 test_56k() {
6509         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6510
6511         setup_56_special $dir $NUMFILES $NUMDIRS
6512
6513         local expected=$(((NUMDIRS + 1) * NUMFILES))
6514         local cmd="$LFS find -type f $dir"
6515         local nums=$($cmd | wc -l)
6516
6517         [ $nums -eq $expected ] ||
6518                 error "'$cmd' wrong: found $nums, expected $expected"
6519 }
6520 run_test 56k "check lfs find -type f"
6521
6522 test_56l() {
6523         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6524
6525         setup_56_special $dir $NUMFILES $NUMDIRS
6526
6527         local expected=$((NUMDIRS + NUMFILES))
6528         local cmd="$LFS find -type b $dir"
6529         local nums=$($cmd | wc -l)
6530
6531         [ $nums -eq $expected ] ||
6532                 error "'$cmd' wrong: found $nums, expected $expected"
6533 }
6534 run_test 56l "check lfs find -type b"
6535
6536 test_56m() {
6537         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6538
6539         setup_56_special $dir $NUMFILES $NUMDIRS
6540
6541         local expected=$((NUMDIRS + NUMFILES))
6542         local cmd="$LFS find -type c $dir"
6543         local nums=$($cmd | wc -l)
6544         [ $nums -eq $expected ] ||
6545                 error "'$cmd' wrong: found $nums, expected $expected"
6546 }
6547 run_test 56m "check lfs find -type c"
6548
6549 test_56n() {
6550         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6551         setup_56_special $dir $NUMFILES $NUMDIRS
6552
6553         local expected=$((NUMDIRS + NUMFILES))
6554         local cmd="$LFS find -type l $dir"
6555         local nums=$($cmd | wc -l)
6556
6557         [ $nums -eq $expected ] ||
6558                 error "'$cmd' wrong: found $nums, expected $expected"
6559 }
6560 run_test 56n "check lfs find -type l"
6561
6562 test_56o() {
6563         local dir=$DIR/$tdir
6564
6565         setup_56 $dir $NUMFILES $NUMDIRS
6566         utime $dir/file1 > /dev/null || error "utime (1)"
6567         utime $dir/file2 > /dev/null || error "utime (2)"
6568         utime $dir/dir1 > /dev/null || error "utime (3)"
6569         utime $dir/dir2 > /dev/null || error "utime (4)"
6570         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6571         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6572
6573         local expected=4
6574         local nums=$($LFS find -mtime +0 $dir | wc -l)
6575
6576         [ $nums -eq $expected ] ||
6577                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6578
6579         expected=12
6580         cmd="$LFS find -mtime 0 $dir"
6581         nums=$($cmd | wc -l)
6582         [ $nums -eq $expected ] ||
6583                 error "'$cmd' wrong: found $nums, expected $expected"
6584 }
6585 run_test 56o "check lfs find -mtime for old files"
6586
6587 test_56ob() {
6588         local dir=$DIR/$tdir
6589         local expected=1
6590         local count=0
6591
6592         # just to make sure there is something that won't be found
6593         test_mkdir $dir
6594         touch $dir/$tfile.now
6595
6596         for age in year week day hour min; do
6597                 count=$((count + 1))
6598
6599                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6600                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6601                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6602
6603                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6604                 local nums=$($cmd | wc -l)
6605                 [ $nums -eq $expected ] ||
6606                         error "'$cmd' wrong: found $nums, expected $expected"
6607
6608                 cmd="$LFS find $dir -atime $count${age:0:1}"
6609                 nums=$($cmd | wc -l)
6610                 [ $nums -eq $expected ] ||
6611                         error "'$cmd' wrong: found $nums, expected $expected"
6612         done
6613
6614         sleep 2
6615         cmd="$LFS find $dir -ctime +1s -type f"
6616         nums=$($cmd | wc -l)
6617         (( $nums == $count * 2 + 1)) ||
6618                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6619 }
6620 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6621
6622 test_newerXY_base() {
6623         local x=$1
6624         local y=$2
6625         local dir=$DIR/$tdir
6626         local ref
6627         local negref
6628
6629         if [ $y == "t" ]; then
6630                 if [ $x == "b" ]; then
6631                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6632                 else
6633                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6634                 fi
6635         else
6636                 ref=$DIR/$tfile.newer.$x$y
6637                 touch $ref || error "touch $ref failed"
6638         fi
6639
6640         echo "before = $ref"
6641         sleep 2
6642         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6643         sleep 2
6644         if [ $y == "t" ]; then
6645                 if [ $x == "b" ]; then
6646                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6647                 else
6648                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6649                 fi
6650         else
6651                 negref=$DIR/$tfile.negnewer.$x$y
6652                 touch $negref || error "touch $negref failed"
6653         fi
6654
6655         echo "after = $negref"
6656         local cmd="$LFS find $dir -newer$x$y $ref"
6657         local nums=$(eval $cmd | wc -l)
6658         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6659
6660         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6661                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6662
6663         cmd="$LFS find $dir ! -newer$x$y $negref"
6664         nums=$(eval $cmd | wc -l)
6665         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6666                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6667
6668         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6669         nums=$(eval $cmd | wc -l)
6670         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6671                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6672
6673         rm -rf $DIR/*
6674 }
6675
6676 test_56oc() {
6677         test_newerXY_base "a" "a"
6678         test_newerXY_base "a" "m"
6679         test_newerXY_base "a" "c"
6680         test_newerXY_base "m" "a"
6681         test_newerXY_base "m" "m"
6682         test_newerXY_base "m" "c"
6683         test_newerXY_base "c" "a"
6684         test_newerXY_base "c" "m"
6685         test_newerXY_base "c" "c"
6686
6687         [[ -n "$sles_version" ]] &&
6688                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6689
6690         test_newerXY_base "a" "t"
6691         test_newerXY_base "m" "t"
6692         test_newerXY_base "c" "t"
6693
6694         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6695            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6696                 ! btime_supported && echo "btime unsupported" && return 0
6697
6698         test_newerXY_base "b" "b"
6699         test_newerXY_base "b" "t"
6700 }
6701 run_test 56oc "check lfs find -newerXY work"
6702
6703 btime_supported() {
6704         local dir=$DIR/$tdir
6705         local rc
6706
6707         mkdir -p $dir
6708         touch $dir/$tfile
6709         $LFS find $dir -btime -1d -type f
6710         rc=$?
6711         rm -rf $dir
6712         return $rc
6713 }
6714
6715 test_56od() {
6716         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6717                 ! btime_supported && skip "btime unsupported on MDS"
6718
6719         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6720                 ! btime_supported && skip "btime unsupported on clients"
6721
6722         local dir=$DIR/$tdir
6723         local ref=$DIR/$tfile.ref
6724         local negref=$DIR/$tfile.negref
6725
6726         mkdir $dir || error "mkdir $dir failed"
6727         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6728         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6729         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6730         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6731         touch $ref || error "touch $ref failed"
6732         # sleep 3 seconds at least
6733         sleep 3
6734
6735         local before=$(do_facet mds1 date +%s)
6736         local skew=$(($(date +%s) - before + 1))
6737
6738         if (( skew < 0 && skew > -5 )); then
6739                 sleep $((0 - skew + 1))
6740                 skew=0
6741         fi
6742
6743         # Set the dir stripe params to limit files all on MDT0,
6744         # otherwise we need to calc the max clock skew between
6745         # the client and MDTs.
6746         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6747         sleep 2
6748         touch $negref || error "touch $negref failed"
6749
6750         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6751         local nums=$($cmd | wc -l)
6752         local expected=$(((NUMFILES + 1) * NUMDIRS))
6753
6754         [ $nums -eq $expected ] ||
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756
6757         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6758         nums=$($cmd | wc -l)
6759         expected=$((NUMFILES + 1))
6760         [ $nums -eq $expected ] ||
6761                 error "'$cmd' wrong: found $nums, expected $expected"
6762
6763         [ $skew -lt 0 ] && return
6764
6765         local after=$(do_facet mds1 date +%s)
6766         local age=$((after - before + 1 + skew))
6767
6768         cmd="$LFS find $dir -btime -${age}s -type f"
6769         nums=$($cmd | wc -l)
6770         expected=$(((NUMFILES + 1) * NUMDIRS))
6771
6772         echo "Clock skew between client and server: $skew, age:$age"
6773         [ $nums -eq $expected ] ||
6774                 error "'$cmd' wrong: found $nums, expected $expected"
6775
6776         expected=$(($NUMDIRS + 1))
6777         cmd="$LFS find $dir -btime -${age}s -type d"
6778         nums=$($cmd | wc -l)
6779         [ $nums -eq $expected ] ||
6780                 error "'$cmd' wrong: found $nums, expected $expected"
6781         rm -f $ref $negref || error "Failed to remove $ref $negref"
6782 }
6783 run_test 56od "check lfs find -btime with units"
6784
6785 test_56p() {
6786         [ $RUNAS_ID -eq $UID ] &&
6787                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6788
6789         local dir=$DIR/$tdir
6790
6791         setup_56 $dir $NUMFILES $NUMDIRS
6792         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6793
6794         local expected=$NUMFILES
6795         local cmd="$LFS find -uid $RUNAS_ID $dir"
6796         local nums=$($cmd | wc -l)
6797
6798         [ $nums -eq $expected ] ||
6799                 error "'$cmd' wrong: found $nums, expected $expected"
6800
6801         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6802         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6803         nums=$($cmd | wc -l)
6804         [ $nums -eq $expected ] ||
6805                 error "'$cmd' wrong: found $nums, expected $expected"
6806 }
6807 run_test 56p "check lfs find -uid and ! -uid"
6808
6809 test_56q() {
6810         [ $RUNAS_ID -eq $UID ] &&
6811                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6812
6813         local dir=$DIR/$tdir
6814
6815         setup_56 $dir $NUMFILES $NUMDIRS
6816         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6817
6818         local expected=$NUMFILES
6819         local cmd="$LFS find -gid $RUNAS_GID $dir"
6820         local nums=$($cmd | wc -l)
6821
6822         [ $nums -eq $expected ] ||
6823                 error "'$cmd' wrong: found $nums, expected $expected"
6824
6825         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6826         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6827         nums=$($cmd | wc -l)
6828         [ $nums -eq $expected ] ||
6829                 error "'$cmd' wrong: found $nums, expected $expected"
6830 }
6831 run_test 56q "check lfs find -gid and ! -gid"
6832
6833 test_56r() {
6834         local dir=$DIR/$tdir
6835
6836         setup_56 $dir $NUMFILES $NUMDIRS
6837
6838         local expected=12
6839         local cmd="$LFS find -size 0 -type f -lazy $dir"
6840         local nums=$($cmd | wc -l)
6841
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844         cmd="$LFS find -size 0 -type f $dir"
6845         nums=$($cmd | wc -l)
6846         [ $nums -eq $expected ] ||
6847                 error "'$cmd' wrong: found $nums, expected $expected"
6848
6849         expected=0
6850         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6851         nums=$($cmd | wc -l)
6852         [ $nums -eq $expected ] ||
6853                 error "'$cmd' wrong: found $nums, expected $expected"
6854         cmd="$LFS find ! -size 0 -type f $dir"
6855         nums=$($cmd | wc -l)
6856         [ $nums -eq $expected ] ||
6857                 error "'$cmd' wrong: found $nums, expected $expected"
6858
6859         echo "test" > $dir/$tfile
6860         echo "test2" > $dir/$tfile.2 && sync
6861         expected=1
6862         cmd="$LFS find -size 5 -type f -lazy $dir"
6863         nums=$($cmd | wc -l)
6864         [ $nums -eq $expected ] ||
6865                 error "'$cmd' wrong: found $nums, expected $expected"
6866         cmd="$LFS find -size 5 -type f $dir"
6867         nums=$($cmd | wc -l)
6868         [ $nums -eq $expected ] ||
6869                 error "'$cmd' wrong: found $nums, expected $expected"
6870
6871         expected=1
6872         cmd="$LFS find -size +5 -type f -lazy $dir"
6873         nums=$($cmd | wc -l)
6874         [ $nums -eq $expected ] ||
6875                 error "'$cmd' wrong: found $nums, expected $expected"
6876         cmd="$LFS find -size +5 -type f $dir"
6877         nums=$($cmd | wc -l)
6878         [ $nums -eq $expected ] ||
6879                 error "'$cmd' wrong: found $nums, expected $expected"
6880
6881         expected=2
6882         cmd="$LFS find -size +0 -type f -lazy $dir"
6883         nums=$($cmd | wc -l)
6884         [ $nums -eq $expected ] ||
6885                 error "'$cmd' wrong: found $nums, expected $expected"
6886         cmd="$LFS find -size +0 -type f $dir"
6887         nums=$($cmd | wc -l)
6888         [ $nums -eq $expected ] ||
6889                 error "'$cmd' wrong: found $nums, expected $expected"
6890
6891         expected=2
6892         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6893         nums=$($cmd | wc -l)
6894         [ $nums -eq $expected ] ||
6895                 error "'$cmd' wrong: found $nums, expected $expected"
6896         cmd="$LFS find ! -size -5 -type f $dir"
6897         nums=$($cmd | wc -l)
6898         [ $nums -eq $expected ] ||
6899                 error "'$cmd' wrong: found $nums, expected $expected"
6900
6901         expected=12
6902         cmd="$LFS find -size -5 -type f -lazy $dir"
6903         nums=$($cmd | wc -l)
6904         [ $nums -eq $expected ] ||
6905                 error "'$cmd' wrong: found $nums, expected $expected"
6906         cmd="$LFS find -size -5 -type f $dir"
6907         nums=$($cmd | wc -l)
6908         [ $nums -eq $expected ] ||
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910 }
6911 run_test 56r "check lfs find -size works"
6912
6913 test_56ra_sub() {
6914         local expected=$1
6915         local glimpses=$2
6916         local cmd="$3"
6917
6918         cancel_lru_locks $OSC
6919
6920         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6921         local nums=$($cmd | wc -l)
6922
6923         [ $nums -eq $expected ] ||
6924                 error "'$cmd' wrong: found $nums, expected $expected"
6925
6926         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6927
6928         if (( rpcs_before + glimpses != rpcs_after )); then
6929                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6930                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6931
6932                 if [[ $glimpses == 0 ]]; then
6933                         error "'$cmd' should not send glimpse RPCs to OST"
6934                 else
6935                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6936                 fi
6937         fi
6938 }
6939
6940 test_56ra() {
6941         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6942                 skip "MDS < 2.12.58 doesn't return LSOM data"
6943         local dir=$DIR/$tdir
6944         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6945
6946         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6947
6948         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6949         $LCTL set_param -n llite.*.statahead_agl=0
6950         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6951
6952         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6953         # open and close all files to ensure LSOM is updated
6954         cancel_lru_locks $OSC
6955         find $dir -type f | xargs cat > /dev/null
6956
6957         #   expect_found  glimpse_rpcs  command_to_run
6958         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6959         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6960         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6961         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6962
6963         echo "test" > $dir/$tfile
6964         echo "test2" > $dir/$tfile.2 && sync
6965         cancel_lru_locks $OSC
6966         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6967
6968         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6969         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6970         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6971         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6972
6973         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6974         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6975         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6976         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6977         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6978         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6979 }
6980 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6981
6982 test_56rb() {
6983         local dir=$DIR/$tdir
6984         local tmp=$TMP/$tfile.log
6985         local mdt_idx;
6986
6987         test_mkdir -p $dir || error "failed to mkdir $dir"
6988         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6989                 error "failed to setstripe $dir/$tfile"
6990         mdt_idx=$($LFS getdirstripe -i $dir)
6991         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6992
6993         stack_trap "rm -f $tmp" EXIT
6994         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6995         ! grep -q obd_uuid $tmp ||
6996                 error "failed to find --size +100K --ost 0 $dir"
6997         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6998         ! grep -q obd_uuid $tmp ||
6999                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7000 }
7001 run_test 56rb "check lfs find --size --ost/--mdt works"
7002
7003 test_56rc() {
7004         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7005         local dir=$DIR/$tdir
7006         local found
7007
7008         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7009         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7010         (( $MDSCOUNT > 2 )) &&
7011                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7012         mkdir $dir/$tdir-{1..10}
7013         touch $dir/$tfile-{1..10}
7014
7015         found=$($LFS find $dir --mdt-count 2 | wc -l)
7016         expect=11
7017         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7018
7019         found=$($LFS find $dir -T +1 | wc -l)
7020         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7021         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7022
7023         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7024         expect=11
7025         (( $found == $expect )) || error "found $found all_char, expect $expect"
7026
7027         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7028         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7029         (( $found == $expect )) || error "found $found all_char, expect $expect"
7030 }
7031 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7032
7033 test_56s() { # LU-611 #LU-9369
7034         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7035
7036         local dir=$DIR/$tdir
7037         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7038
7039         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7040         for i in $(seq $NUMDIRS); do
7041                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7042         done
7043
7044         local expected=$NUMDIRS
7045         local cmd="$LFS find -c $OSTCOUNT $dir"
7046         local nums=$($cmd | wc -l)
7047
7048         [ $nums -eq $expected ] || {
7049                 $LFS getstripe -R $dir
7050                 error "'$cmd' wrong: found $nums, expected $expected"
7051         }
7052
7053         expected=$((NUMDIRS + onestripe))
7054         cmd="$LFS find -stripe-count +0 -type f $dir"
7055         nums=$($cmd | wc -l)
7056         [ $nums -eq $expected ] || {
7057                 $LFS getstripe -R $dir
7058                 error "'$cmd' wrong: found $nums, expected $expected"
7059         }
7060
7061         expected=$onestripe
7062         cmd="$LFS find -stripe-count 1 -type f $dir"
7063         nums=$($cmd | wc -l)
7064         [ $nums -eq $expected ] || {
7065                 $LFS getstripe -R $dir
7066                 error "'$cmd' wrong: found $nums, expected $expected"
7067         }
7068
7069         cmd="$LFS find -stripe-count -2 -type f $dir"
7070         nums=$($cmd | wc -l)
7071         [ $nums -eq $expected ] || {
7072                 $LFS getstripe -R $dir
7073                 error "'$cmd' wrong: found $nums, expected $expected"
7074         }
7075
7076         expected=0
7077         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7078         nums=$($cmd | wc -l)
7079         [ $nums -eq $expected ] || {
7080                 $LFS getstripe -R $dir
7081                 error "'$cmd' wrong: found $nums, expected $expected"
7082         }
7083 }
7084 run_test 56s "check lfs find -stripe-count works"
7085
7086 test_56t() { # LU-611 #LU-9369
7087         local dir=$DIR/$tdir
7088
7089         setup_56 $dir 0 $NUMDIRS
7090         for i in $(seq $NUMDIRS); do
7091                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7092         done
7093
7094         local expected=$NUMDIRS
7095         local cmd="$LFS find -S 8M $dir"
7096         local nums=$($cmd | wc -l)
7097
7098         [ $nums -eq $expected ] || {
7099                 $LFS getstripe -R $dir
7100                 error "'$cmd' wrong: found $nums, expected $expected"
7101         }
7102         rm -rf $dir
7103
7104         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7105
7106         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7107
7108         expected=$(((NUMDIRS + 1) * NUMFILES))
7109         cmd="$LFS find -stripe-size 512k -type f $dir"
7110         nums=$($cmd | wc -l)
7111         [ $nums -eq $expected ] ||
7112                 error "'$cmd' wrong: found $nums, expected $expected"
7113
7114         cmd="$LFS find -stripe-size +320k -type f $dir"
7115         nums=$($cmd | wc -l)
7116         [ $nums -eq $expected ] ||
7117                 error "'$cmd' wrong: found $nums, expected $expected"
7118
7119         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7120         cmd="$LFS find -stripe-size +200k -type f $dir"
7121         nums=$($cmd | wc -l)
7122         [ $nums -eq $expected ] ||
7123                 error "'$cmd' wrong: found $nums, expected $expected"
7124
7125         cmd="$LFS find -stripe-size -640k -type f $dir"
7126         nums=$($cmd | wc -l)
7127         [ $nums -eq $expected ] ||
7128                 error "'$cmd' wrong: found $nums, expected $expected"
7129
7130         expected=4
7131         cmd="$LFS find -stripe-size 256k -type f $dir"
7132         nums=$($cmd | wc -l)
7133         [ $nums -eq $expected ] ||
7134                 error "'$cmd' wrong: found $nums, expected $expected"
7135
7136         cmd="$LFS find -stripe-size -320k -type f $dir"
7137         nums=$($cmd | wc -l)
7138         [ $nums -eq $expected ] ||
7139                 error "'$cmd' wrong: found $nums, expected $expected"
7140
7141         expected=0
7142         cmd="$LFS find -stripe-size 1024k -type f $dir"
7143         nums=$($cmd | wc -l)
7144         [ $nums -eq $expected ] ||
7145                 error "'$cmd' wrong: found $nums, expected $expected"
7146 }
7147 run_test 56t "check lfs find -stripe-size works"
7148
7149 test_56u() { # LU-611
7150         local dir=$DIR/$tdir
7151
7152         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7153
7154         if [[ $OSTCOUNT -gt 1 ]]; then
7155                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7156                 onestripe=4
7157         else
7158                 onestripe=0
7159         fi
7160
7161         local expected=$(((NUMDIRS + 1) * NUMFILES))
7162         local cmd="$LFS find -stripe-index 0 -type f $dir"
7163         local nums=$($cmd | wc -l)
7164
7165         [ $nums -eq $expected ] ||
7166                 error "'$cmd' wrong: found $nums, expected $expected"
7167
7168         expected=$onestripe
7169         cmd="$LFS find -stripe-index 1 -type f $dir"
7170         nums=$($cmd | wc -l)
7171         [ $nums -eq $expected ] ||
7172                 error "'$cmd' wrong: found $nums, expected $expected"
7173
7174         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7175         nums=$($cmd | wc -l)
7176         [ $nums -eq $expected ] ||
7177                 error "'$cmd' wrong: found $nums, expected $expected"
7178
7179         expected=0
7180         # This should produce an error and not return any files
7181         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7182         nums=$($cmd 2>/dev/null | wc -l)
7183         [ $nums -eq $expected ] ||
7184                 error "'$cmd' wrong: found $nums, expected $expected"
7185
7186         if [[ $OSTCOUNT -gt 1 ]]; then
7187                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7188                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7189                 nums=$($cmd | wc -l)
7190                 [ $nums -eq $expected ] ||
7191                         error "'$cmd' wrong: found $nums, expected $expected"
7192         fi
7193 }
7194 run_test 56u "check lfs find -stripe-index works"
7195
7196 test_56v() {
7197         local mdt_idx=0
7198         local dir=$DIR/$tdir
7199
7200         setup_56 $dir $NUMFILES $NUMDIRS
7201
7202         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7203         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7204
7205         for file in $($LFS find -m $UUID $dir); do
7206                 file_midx=$($LFS getstripe -m $file)
7207                 [ $file_midx -eq $mdt_idx ] ||
7208                         error "lfs find -m $UUID != getstripe -m $file_midx"
7209         done
7210 }
7211 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7212
7213 test_56w() {
7214         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7216
7217         local dir=$DIR/$tdir
7218
7219         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7220
7221         local stripe_size=$($LFS getstripe -S -d $dir) ||
7222                 error "$LFS getstripe -S -d $dir failed"
7223         stripe_size=${stripe_size%% *}
7224
7225         local file_size=$((stripe_size * OSTCOUNT))
7226         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7227         local required_space=$((file_num * file_size))
7228         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7229                            head -n1)
7230         [[ $free_space -le $((required_space / 1024)) ]] &&
7231                 skip_env "need $required_space, have $free_space kbytes"
7232
7233         local dd_bs=65536
7234         local dd_count=$((file_size / dd_bs))
7235
7236         # write data into the files
7237         local i
7238         local j
7239         local file
7240
7241         for i in $(seq $NUMFILES); do
7242                 file=$dir/file$i
7243                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7244                         error "write data into $file failed"
7245         done
7246         for i in $(seq $NUMDIRS); do
7247                 for j in $(seq $NUMFILES); do
7248                         file=$dir/dir$i/file$j
7249                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7250                                 error "write data into $file failed"
7251                 done
7252         done
7253
7254         # $LFS_MIGRATE will fail if hard link migration is unsupported
7255         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7256                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7257                         error "creating links to $dir/dir1/file1 failed"
7258         fi
7259
7260         local expected=-1
7261
7262         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7263
7264         # lfs_migrate file
7265         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7266
7267         echo "$cmd"
7268         eval $cmd || error "$cmd failed"
7269
7270         check_stripe_count $dir/file1 $expected
7271
7272         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7273         then
7274                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7275                 # OST 1 if it is on OST 0. This file is small enough to
7276                 # be on only one stripe.
7277                 file=$dir/migr_1_ost
7278                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7279                         error "write data into $file failed"
7280                 local obdidx=$($LFS getstripe -i $file)
7281                 local oldmd5=$(md5sum $file)
7282                 local newobdidx=0
7283
7284                 [[ $obdidx -eq 0 ]] && newobdidx=1
7285                 cmd="$LFS migrate -i $newobdidx $file"
7286                 echo $cmd
7287                 eval $cmd || error "$cmd failed"
7288
7289                 local realobdix=$($LFS getstripe -i $file)
7290                 local newmd5=$(md5sum $file)
7291
7292                 [[ $newobdidx -ne $realobdix ]] &&
7293                         error "new OST is different (was=$obdidx, "\
7294                               "wanted=$newobdidx, got=$realobdix)"
7295                 [[ "$oldmd5" != "$newmd5" ]] &&
7296                         error "md5sum differ: $oldmd5, $newmd5"
7297         fi
7298
7299         # lfs_migrate dir
7300         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7301         echo "$cmd"
7302         eval $cmd || error "$cmd failed"
7303
7304         for j in $(seq $NUMFILES); do
7305                 check_stripe_count $dir/dir1/file$j $expected
7306         done
7307
7308         # lfs_migrate works with lfs find
7309         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7310              $LFS_MIGRATE -y -c $expected"
7311         echo "$cmd"
7312         eval $cmd || error "$cmd failed"
7313
7314         for i in $(seq 2 $NUMFILES); do
7315                 check_stripe_count $dir/file$i $expected
7316         done
7317         for i in $(seq 2 $NUMDIRS); do
7318                 for j in $(seq $NUMFILES); do
7319                 check_stripe_count $dir/dir$i/file$j $expected
7320                 done
7321         done
7322 }
7323 run_test 56w "check lfs_migrate -c stripe_count works"
7324
7325 test_56wb() {
7326         local file1=$DIR/$tdir/file1
7327         local create_pool=false
7328         local initial_pool=$($LFS getstripe -p $DIR)
7329         local pool_list=()
7330         local pool=""
7331
7332         echo -n "Creating test dir..."
7333         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7334         echo "done."
7335
7336         echo -n "Creating test file..."
7337         touch $file1 || error "cannot create file"
7338         echo "done."
7339
7340         echo -n "Detecting existing pools..."
7341         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7342
7343         if [ ${#pool_list[@]} -gt 0 ]; then
7344                 echo "${pool_list[@]}"
7345                 for thispool in "${pool_list[@]}"; do
7346                         if [[ -z "$initial_pool" ||
7347                               "$initial_pool" != "$thispool" ]]; then
7348                                 pool="$thispool"
7349                                 echo "Using existing pool '$pool'"
7350                                 break
7351                         fi
7352                 done
7353         else
7354                 echo "none detected."
7355         fi
7356         if [ -z "$pool" ]; then
7357                 pool=${POOL:-testpool}
7358                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7359                 echo -n "Creating pool '$pool'..."
7360                 create_pool=true
7361                 pool_add $pool &> /dev/null ||
7362                         error "pool_add failed"
7363                 echo "done."
7364
7365                 echo -n "Adding target to pool..."
7366                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7367                         error "pool_add_targets failed"
7368                 echo "done."
7369         fi
7370
7371         echo -n "Setting pool using -p option..."
7372         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7373                 error "migrate failed rc = $?"
7374         echo "done."
7375
7376         echo -n "Verifying test file is in pool after migrating..."
7377         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7378                 error "file was not migrated to pool $pool"
7379         echo "done."
7380
7381         echo -n "Removing test file from pool '$pool'..."
7382         # "lfs migrate $file" won't remove the file from the pool
7383         # until some striping information is changed.
7384         $LFS migrate -c 1 $file1 &> /dev/null ||
7385                 error "cannot remove from pool"
7386         [ "$($LFS getstripe -p $file1)" ] &&
7387                 error "pool still set"
7388         echo "done."
7389
7390         echo -n "Setting pool using --pool option..."
7391         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7392                 error "migrate failed rc = $?"
7393         echo "done."
7394
7395         # Clean up
7396         rm -f $file1
7397         if $create_pool; then
7398                 destroy_test_pools 2> /dev/null ||
7399                         error "destroy test pools failed"
7400         fi
7401 }
7402 run_test 56wb "check lfs_migrate pool support"
7403
7404 test_56wc() {
7405         local file1="$DIR/$tdir/file1"
7406         local parent_ssize
7407         local parent_scount
7408         local cur_ssize
7409         local cur_scount
7410         local orig_ssize
7411
7412         echo -n "Creating test dir..."
7413         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7414         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7415                 error "cannot set stripe by '-S 1M -c 1'"
7416         echo "done"
7417
7418         echo -n "Setting initial stripe for test file..."
7419         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7420                 error "cannot set stripe"
7421         cur_ssize=$($LFS getstripe -S "$file1")
7422         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7423         echo "done."
7424
7425         # File currently set to -S 512K -c 1
7426
7427         # Ensure -c and -S options are rejected when -R is set
7428         echo -n "Verifying incompatible options are detected..."
7429         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7430                 error "incompatible -c and -R options not detected"
7431         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7432                 error "incompatible -S and -R options not detected"
7433         echo "done."
7434
7435         # Ensure unrecognized options are passed through to 'lfs migrate'
7436         echo -n "Verifying -S option is passed through to lfs migrate..."
7437         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7438                 error "migration failed"
7439         cur_ssize=$($LFS getstripe -S "$file1")
7440         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7441         echo "done."
7442
7443         # File currently set to -S 1M -c 1
7444
7445         # Ensure long options are supported
7446         echo -n "Verifying long options supported..."
7447         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7448                 error "long option without argument not supported"
7449         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7450                 error "long option with argument not supported"
7451         cur_ssize=$($LFS getstripe -S "$file1")
7452         [ $cur_ssize -eq 524288 ] ||
7453                 error "migrate --stripe-size $cur_ssize != 524288"
7454         echo "done."
7455
7456         # File currently set to -S 512K -c 1
7457
7458         if [ "$OSTCOUNT" -gt 1 ]; then
7459                 echo -n "Verifying explicit stripe count can be set..."
7460                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7461                         error "migrate failed"
7462                 cur_scount=$($LFS getstripe -c "$file1")
7463                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7464                 echo "done."
7465         fi
7466
7467         # File currently set to -S 512K -c 1 or -S 512K -c 2
7468
7469         # Ensure parent striping is used if -R is set, and no stripe
7470         # count or size is specified
7471         echo -n "Setting stripe for parent directory..."
7472         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7473                 error "cannot set stripe '-S 2M -c 1'"
7474         echo "done."
7475
7476         echo -n "Verifying restripe option uses parent stripe settings..."
7477         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7478         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7479         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7480                 error "migrate failed"
7481         cur_ssize=$($LFS getstripe -S "$file1")
7482         [ $cur_ssize -eq $parent_ssize ] ||
7483                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7484         cur_scount=$($LFS getstripe -c "$file1")
7485         [ $cur_scount -eq $parent_scount ] ||
7486                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7487         echo "done."
7488
7489         # File currently set to -S 1M -c 1
7490
7491         # Ensure striping is preserved if -R is not set, and no stripe
7492         # count or size is specified
7493         echo -n "Verifying striping size preserved when not specified..."
7494         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7495         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7496                 error "cannot set stripe on parent directory"
7497         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7498                 error "migrate failed"
7499         cur_ssize=$($LFS getstripe -S "$file1")
7500         [ $cur_ssize -eq $orig_ssize ] ||
7501                 error "migrate by default $cur_ssize != $orig_ssize"
7502         echo "done."
7503
7504         # Ensure file name properly detected when final option has no argument
7505         echo -n "Verifying file name properly detected..."
7506         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7507                 error "file name interpreted as option argument"
7508         echo "done."
7509
7510         # Clean up
7511         rm -f "$file1"
7512 }
7513 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7514
7515 test_56wd() {
7516         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7517
7518         local file1=$DIR/$tdir/file1
7519
7520         echo -n "Creating test dir..."
7521         test_mkdir $DIR/$tdir || error "cannot create dir"
7522         echo "done."
7523
7524         echo -n "Creating test file..."
7525         touch $file1
7526         echo "done."
7527
7528         # Ensure 'lfs migrate' will fail by using a non-existent option,
7529         # and make sure rsync is not called to recover
7530         echo -n "Make sure --no-rsync option works..."
7531         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7532                 grep -q 'refusing to fall back to rsync' ||
7533                 error "rsync was called with --no-rsync set"
7534         echo "done."
7535
7536         # Ensure rsync is called without trying 'lfs migrate' first
7537         echo -n "Make sure --rsync option works..."
7538         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7539                 grep -q 'falling back to rsync' &&
7540                 error "lfs migrate was called with --rsync set"
7541         echo "done."
7542
7543         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7544         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7545                 grep -q 'at the same time' ||
7546                 error "--rsync and --no-rsync accepted concurrently"
7547         echo "done."
7548
7549         # Clean up
7550         rm -f $file1
7551 }
7552 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7553
7554 test_56we() {
7555         local td=$DIR/$tdir
7556         local tf=$td/$tfile
7557
7558         test_mkdir $td || error "cannot create $td"
7559         touch $tf || error "cannot touch $tf"
7560
7561         echo -n "Make sure --non-direct|-D works..."
7562         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7563                 grep -q "lfs migrate --non-direct" ||
7564                 error "--non-direct option cannot work correctly"
7565         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7566                 grep -q "lfs migrate -D" ||
7567                 error "-D option cannot work correctly"
7568         echo "done."
7569 }
7570 run_test 56we "check lfs_migrate --non-direct|-D support"
7571
7572 test_56x() {
7573         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7574         check_swap_layouts_support
7575
7576         local dir=$DIR/$tdir
7577         local ref1=/etc/passwd
7578         local file1=$dir/file1
7579
7580         test_mkdir $dir || error "creating dir $dir"
7581         $LFS setstripe -c 2 $file1
7582         cp $ref1 $file1
7583         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7584         stripe=$($LFS getstripe -c $file1)
7585         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7586         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7587
7588         # clean up
7589         rm -f $file1
7590 }
7591 run_test 56x "lfs migration support"
7592
7593 test_56xa() {
7594         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7595         check_swap_layouts_support
7596
7597         local dir=$DIR/$tdir/$testnum
7598
7599         test_mkdir -p $dir
7600
7601         local ref1=/etc/passwd
7602         local file1=$dir/file1
7603
7604         $LFS setstripe -c 2 $file1
7605         cp $ref1 $file1
7606         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7607
7608         local stripe=$($LFS getstripe -c $file1)
7609
7610         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7611         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7612
7613         # clean up
7614         rm -f $file1
7615 }
7616 run_test 56xa "lfs migration --block support"
7617
7618 check_migrate_links() {
7619         local dir="$1"
7620         local file1="$dir/file1"
7621         local begin="$2"
7622         local count="$3"
7623         local runas="$4"
7624         local total_count=$(($begin + $count - 1))
7625         local symlink_count=10
7626         local uniq_count=10
7627
7628         if [ ! -f "$file1" ]; then
7629                 echo -n "creating initial file..."
7630                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7631                         error "cannot setstripe initial file"
7632                 echo "done"
7633
7634                 echo -n "creating symlinks..."
7635                 for s in $(seq 1 $symlink_count); do
7636                         ln -s "$file1" "$dir/slink$s" ||
7637                                 error "cannot create symlinks"
7638                 done
7639                 echo "done"
7640
7641                 echo -n "creating nonlinked files..."
7642                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7643                         error "cannot create nonlinked files"
7644                 echo "done"
7645         fi
7646
7647         # create hard links
7648         if [ ! -f "$dir/file$total_count" ]; then
7649                 echo -n "creating hard links $begin:$total_count..."
7650                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7651                         /dev/null || error "cannot create hard links"
7652                 echo "done"
7653         fi
7654
7655         echo -n "checking number of hard links listed in xattrs..."
7656         local fid=$($LFS getstripe -F "$file1")
7657         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7658
7659         echo "${#paths[*]}"
7660         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7661                         skip "hard link list has unexpected size, skipping test"
7662         fi
7663         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7664                         error "link names should exceed xattrs size"
7665         fi
7666
7667         echo -n "migrating files..."
7668         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7669         local rc=$?
7670         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7671         echo "done"
7672
7673         # make sure all links have been properly migrated
7674         echo -n "verifying files..."
7675         fid=$($LFS getstripe -F "$file1") ||
7676                 error "cannot get fid for file $file1"
7677         for i in $(seq 2 $total_count); do
7678                 local fid2=$($LFS getstripe -F $dir/file$i)
7679
7680                 [ "$fid2" == "$fid" ] ||
7681                         error "migrated hard link has mismatched FID"
7682         done
7683
7684         # make sure hard links were properly detected, and migration was
7685         # performed only once for the entire link set; nonlinked files should
7686         # also be migrated
7687         local actual=$(grep -c 'done' <<< "$migrate_out")
7688         local expected=$(($uniq_count + 1))
7689
7690         [ "$actual" -eq  "$expected" ] ||
7691                 error "hard links individually migrated ($actual != $expected)"
7692
7693         # make sure the correct number of hard links are present
7694         local hardlinks=$(stat -c '%h' "$file1")
7695
7696         [ $hardlinks -eq $total_count ] ||
7697                 error "num hard links $hardlinks != $total_count"
7698         echo "done"
7699
7700         return 0
7701 }
7702
7703 test_56xb() {
7704         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7705                 skip "Need MDS version at least 2.10.55"
7706
7707         local dir="$DIR/$tdir"
7708
7709         test_mkdir "$dir" || error "cannot create dir $dir"
7710
7711         echo "testing lfs migrate mode when all links fit within xattrs"
7712         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7713
7714         echo "testing rsync mode when all links fit within xattrs"
7715         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7716
7717         echo "testing lfs migrate mode when all links do not fit within xattrs"
7718         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7719
7720         echo "testing rsync mode when all links do not fit within xattrs"
7721         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7722
7723         chown -R $RUNAS_ID $dir
7724         echo "testing non-root lfs migrate mode when not all links are in xattr"
7725         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7726
7727         # clean up
7728         rm -rf $dir
7729 }
7730 run_test 56xb "lfs migration hard link support"
7731
7732 test_56xc() {
7733         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7734
7735         local dir="$DIR/$tdir"
7736
7737         test_mkdir "$dir" || error "cannot create dir $dir"
7738
7739         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7740         echo -n "Setting initial stripe for 20MB test file..."
7741         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7742                 error "cannot setstripe 20MB file"
7743         echo "done"
7744         echo -n "Sizing 20MB test file..."
7745         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7746         echo "done"
7747         echo -n "Verifying small file autostripe count is 1..."
7748         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7749                 error "cannot migrate 20MB file"
7750         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7751                 error "cannot get stripe for $dir/20mb"
7752         [ $stripe_count -eq 1 ] ||
7753                 error "unexpected stripe count $stripe_count for 20MB file"
7754         rm -f "$dir/20mb"
7755         echo "done"
7756
7757         # Test 2: File is small enough to fit within the available space on
7758         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7759         # have at least an additional 1KB for each desired stripe for test 3
7760         echo -n "Setting stripe for 1GB test file..."
7761         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7762         echo "done"
7763         echo -n "Sizing 1GB test file..."
7764         # File size is 1GB + 3KB
7765         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7766         echo "done"
7767
7768         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7769         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7770         if (( avail > 524288 * OSTCOUNT )); then
7771                 echo -n "Migrating 1GB file..."
7772                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7773                         error "cannot migrate 1GB file"
7774                 echo "done"
7775                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7776                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7777                         error "cannot getstripe for 1GB file"
7778                 [ $stripe_count -eq 2 ] ||
7779                         error "unexpected stripe count $stripe_count != 2"
7780                 echo "done"
7781         fi
7782
7783         # Test 3: File is too large to fit within the available space on
7784         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7785         if [ $OSTCOUNT -ge 3 ]; then
7786                 # The required available space is calculated as
7787                 # file size (1GB + 3KB) / OST count (3).
7788                 local kb_per_ost=349526
7789
7790                 echo -n "Migrating 1GB file with limit..."
7791                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7792                         error "cannot migrate 1GB file with limit"
7793                 echo "done"
7794
7795                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7796                 echo -n "Verifying 1GB autostripe count with limited space..."
7797                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7798                         error "unexpected stripe count $stripe_count (min 3)"
7799                 echo "done"
7800         fi
7801
7802         # clean up
7803         rm -rf $dir
7804 }
7805 run_test 56xc "lfs migration autostripe"
7806
7807 test_56xd() {
7808         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7809
7810         local dir=$DIR/$tdir
7811         local f_mgrt=$dir/$tfile.mgrt
7812         local f_yaml=$dir/$tfile.yaml
7813         local f_copy=$dir/$tfile.copy
7814         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7815         local layout_copy="-c 2 -S 2M -i 1"
7816         local yamlfile=$dir/yamlfile
7817         local layout_before;
7818         local layout_after;
7819
7820         test_mkdir "$dir" || error "cannot create dir $dir"
7821         $LFS setstripe $layout_yaml $f_yaml ||
7822                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7823         $LFS getstripe --yaml $f_yaml > $yamlfile
7824         $LFS setstripe $layout_copy $f_copy ||
7825                 error "cannot setstripe $f_copy with layout $layout_copy"
7826         touch $f_mgrt
7827         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7828
7829         # 1. test option --yaml
7830         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7831                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7832         layout_before=$(get_layout_param $f_yaml)
7833         layout_after=$(get_layout_param $f_mgrt)
7834         [ "$layout_after" == "$layout_before" ] ||
7835                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7836
7837         # 2. test option --copy
7838         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7839                 error "cannot migrate $f_mgrt with --copy $f_copy"
7840         layout_before=$(get_layout_param $f_copy)
7841         layout_after=$(get_layout_param $f_mgrt)
7842         [ "$layout_after" == "$layout_before" ] ||
7843                 error "lfs_migrate --copy: $layout_after != $layout_before"
7844 }
7845 run_test 56xd "check lfs_migrate --yaml and --copy support"
7846
7847 test_56xe() {
7848         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7849
7850         local dir=$DIR/$tdir
7851         local f_comp=$dir/$tfile
7852         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7853         local layout_before=""
7854         local layout_after=""
7855
7856         test_mkdir "$dir" || error "cannot create dir $dir"
7857         $LFS setstripe $layout $f_comp ||
7858                 error "cannot setstripe $f_comp with layout $layout"
7859         layout_before=$(get_layout_param $f_comp)
7860         dd if=/dev/zero of=$f_comp bs=1M count=4
7861
7862         # 1. migrate a comp layout file by lfs_migrate
7863         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7864         layout_after=$(get_layout_param $f_comp)
7865         [ "$layout_before" == "$layout_after" ] ||
7866                 error "lfs_migrate: $layout_before != $layout_after"
7867
7868         # 2. migrate a comp layout file by lfs migrate
7869         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7870         layout_after=$(get_layout_param $f_comp)
7871         [ "$layout_before" == "$layout_after" ] ||
7872                 error "lfs migrate: $layout_before != $layout_after"
7873 }
7874 run_test 56xe "migrate a composite layout file"
7875
7876 test_56xf() {
7877         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7878
7879         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7880                 skip "Need server version at least 2.13.53"
7881
7882         local dir=$DIR/$tdir
7883         local f_comp=$dir/$tfile
7884         local layout="-E 1M -c1 -E -1 -c2"
7885         local fid_before=""
7886         local fid_after=""
7887
7888         test_mkdir "$dir" || error "cannot create dir $dir"
7889         $LFS setstripe $layout $f_comp ||
7890                 error "cannot setstripe $f_comp with layout $layout"
7891         fid_before=$($LFS getstripe --fid $f_comp)
7892         dd if=/dev/zero of=$f_comp bs=1M count=4
7893
7894         # 1. migrate a comp layout file to a comp layout
7895         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7896         fid_after=$($LFS getstripe --fid $f_comp)
7897         [ "$fid_before" == "$fid_after" ] ||
7898                 error "comp-to-comp migrate: $fid_before != $fid_after"
7899
7900         # 2. migrate a comp layout file to a plain layout
7901         $LFS migrate -c2 $f_comp ||
7902                 error "cannot migrate $f_comp by lfs migrate"
7903         fid_after=$($LFS getstripe --fid $f_comp)
7904         [ "$fid_before" == "$fid_after" ] ||
7905                 error "comp-to-plain migrate: $fid_before != $fid_after"
7906
7907         # 3. migrate a plain layout file to a comp layout
7908         $LFS migrate $layout $f_comp ||
7909                 error "cannot migrate $f_comp by lfs migrate"
7910         fid_after=$($LFS getstripe --fid $f_comp)
7911         [ "$fid_before" == "$fid_after" ] ||
7912                 error "plain-to-comp migrate: $fid_before != $fid_after"
7913 }
7914 run_test 56xf "FID is not lost during migration of a composite layout file"
7915
7916 check_file_ost_range() {
7917         local file="$1"
7918         shift
7919         local range="$*"
7920         local -a file_range
7921         local idx
7922
7923         file_range=($($LFS getstripe -y "$file" |
7924                 awk '/l_ost_idx:/ { print $NF }'))
7925
7926         if [[ "${#file_range[@]}" = 0 ]]; then
7927                 echo "No osts found for $file"
7928                 return 1
7929         fi
7930
7931         for idx in "${file_range[@]}"; do
7932                 [[ " $range " =~ " $idx " ]] ||
7933                         return 1
7934         done
7935
7936         return 0
7937 }
7938
7939 sub_test_56xg() {
7940         local stripe_opt="$1"
7941         local pool="$2"
7942         shift 2
7943         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7944
7945         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7946                 error "Fail to migrate $tfile on $pool"
7947         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7948                 error "$tfile is not in pool $pool"
7949         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7950                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7951 }
7952
7953 test_56xg() {
7954         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7955         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7956         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7957                 skip "Need MDS version newer than 2.14.52"
7958
7959         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7960         local -a pool_ranges=("0 0" "1 1" "0 1")
7961
7962         # init pools
7963         for i in "${!pool_names[@]}"; do
7964                 pool_add ${pool_names[$i]} ||
7965                         error "pool_add failed (pool: ${pool_names[$i]})"
7966                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7967                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7968         done
7969
7970         # init the file to migrate
7971         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7972                 error "Unable to create $tfile on OST1"
7973         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7974                 error "Unable to write on $tfile"
7975
7976         echo "1. migrate $tfile on pool ${pool_names[0]}"
7977         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7978
7979         echo "2. migrate $tfile on pool ${pool_names[2]}"
7980         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7981
7982         echo "3. migrate $tfile on pool ${pool_names[1]}"
7983         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7984
7985         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7986         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7987         echo
7988
7989         # Clean pools
7990         destroy_test_pools ||
7991                 error "pool_destroy failed"
7992 }
7993 run_test 56xg "lfs migrate pool support"
7994
7995 test_56y() {
7996         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7997                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7998
7999         local res=""
8000         local dir=$DIR/$tdir
8001         local f1=$dir/file1
8002         local f2=$dir/file2
8003
8004         test_mkdir -p $dir || error "creating dir $dir"
8005         touch $f1 || error "creating std file $f1"
8006         $MULTIOP $f2 H2c || error "creating released file $f2"
8007
8008         # a directory can be raid0, so ask only for files
8009         res=$($LFS find $dir -L raid0 -type f | wc -l)
8010         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8011
8012         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8013         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8014
8015         # only files can be released, so no need to force file search
8016         res=$($LFS find $dir -L released)
8017         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8018
8019         res=$($LFS find $dir -type f \! -L released)
8020         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8021 }
8022 run_test 56y "lfs find -L raid0|released"
8023
8024 test_56z() { # LU-4824
8025         # This checks to make sure 'lfs find' continues after errors
8026         # There are two classes of errors that should be caught:
8027         # - If multiple paths are provided, all should be searched even if one
8028         #   errors out
8029         # - If errors are encountered during the search, it should not terminate
8030         #   early
8031         local dir=$DIR/$tdir
8032         local i
8033
8034         test_mkdir $dir
8035         for i in d{0..9}; do
8036                 test_mkdir $dir/$i
8037                 touch $dir/$i/$tfile
8038         done
8039         $LFS find $DIR/non_existent_dir $dir &&
8040                 error "$LFS find did not return an error"
8041         # Make a directory unsearchable. This should NOT be the last entry in
8042         # directory order.  Arbitrarily pick the 6th entry
8043         chmod 700 $($LFS find $dir -type d | sed '6!d')
8044
8045         $RUNAS $LFS find $DIR/non_existent $dir
8046         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8047
8048         # The user should be able to see 10 directories and 9 files
8049         (( count == 19 )) ||
8050                 error "$LFS find found $count != 19 entries after error"
8051 }
8052 run_test 56z "lfs find should continue after an error"
8053
8054 test_56aa() { # LU-5937
8055         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8056
8057         local dir=$DIR/$tdir
8058
8059         mkdir $dir
8060         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8061
8062         createmany -o $dir/striped_dir/${tfile}- 1024
8063         local dirs=$($LFS find --size +8k $dir/)
8064
8065         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8066 }
8067 run_test 56aa "lfs find --size under striped dir"
8068
8069 test_56ab() { # LU-10705
8070         test_mkdir $DIR/$tdir
8071         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8072         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8073         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8074         # Flush writes to ensure valid blocks.  Need to be more thorough for
8075         # ZFS, since blocks are not allocated/returned to client immediately.
8076         sync_all_data
8077         wait_zfs_commit ost1 2
8078         cancel_lru_locks osc
8079         ls -ls $DIR/$tdir
8080
8081         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8082
8083         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8084
8085         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8086         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8087
8088         rm -f $DIR/$tdir/$tfile.[123]
8089 }
8090 run_test 56ab "lfs find --blocks"
8091
8092 # LU-11188
8093 test_56aca() {
8094         local dir="$DIR/$tdir"
8095         local perms=(001 002 003 004 005 006 007
8096                      010 020 030 040 050 060 070
8097                      100 200 300 400 500 600 700
8098                      111 222 333 444 555 666 777)
8099         local perm_minus=(8 8 4 8 4 4 2
8100                           8 8 4 8 4 4 2
8101                           8 8 4 8 4 4 2
8102                           4 4 2 4 2 2 1)
8103         local perm_slash=(8  8 12  8 12 12 14
8104                           8  8 12  8 12 12 14
8105                           8  8 12  8 12 12 14
8106                          16 16 24 16 24 24 28)
8107
8108         test_mkdir "$dir"
8109         for perm in ${perms[*]}; do
8110                 touch "$dir/$tfile.$perm"
8111                 chmod $perm "$dir/$tfile.$perm"
8112         done
8113
8114         for ((i = 0; i < ${#perms[*]}; i++)); do
8115                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8116                 (( $num == 1 )) ||
8117                         error "lfs find -perm ${perms[i]}:"\
8118                               "$num != 1"
8119
8120                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8121                 (( $num == ${perm_minus[i]} )) ||
8122                         error "lfs find -perm -${perms[i]}:"\
8123                               "$num != ${perm_minus[i]}"
8124
8125                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8126                 (( $num == ${perm_slash[i]} )) ||
8127                         error "lfs find -perm /${perms[i]}:"\
8128                               "$num != ${perm_slash[i]}"
8129         done
8130 }
8131 run_test 56aca "check lfs find -perm with octal representation"
8132
8133 test_56acb() {
8134         local dir=$DIR/$tdir
8135         # p is the permission of write and execute for user, group and other
8136         # without the umask. It is used to test +wx.
8137         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8138         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8139         local symbolic=(+t  a+t u+t g+t o+t
8140                         g+s u+s o+s +s o+sr
8141                         o=r,ug+o,u+w
8142                         u+ g+ o+ a+ ugo+
8143                         u- g- o- a- ugo-
8144                         u= g= o= a= ugo=
8145                         o=r,ug+o,u+w u=r,a+u,u+w
8146                         g=r,ugo=g,u+w u+x,+X +X
8147                         u+x,u+X u+X u+x,g+X o+r,+X
8148                         u+x,go+X +wx +rwx)
8149
8150         test_mkdir $dir
8151         for perm in ${perms[*]}; do
8152                 touch "$dir/$tfile.$perm"
8153                 chmod $perm "$dir/$tfile.$perm"
8154         done
8155
8156         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8157                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8158
8159                 (( $num == 1 )) ||
8160                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8161         done
8162 }
8163 run_test 56acb "check lfs find -perm with symbolic representation"
8164
8165 test_56acc() {
8166         local dir=$DIR/$tdir
8167         local tests="17777 787 789 abcd
8168                 ug=uu ug=a ug=gu uo=ou urw
8169                 u+xg+x a=r,u+x,"
8170
8171         test_mkdir $dir
8172         for err in $tests; do
8173                 if $LFS find $dir -perm $err 2>/dev/null; then
8174                         error "lfs find -perm $err: parsing should have failed"
8175                 fi
8176         done
8177 }
8178 run_test 56acc "check parsing error for lfs find -perm"
8179
8180 test_56ba() {
8181         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8182                 skip "Need MDS version at least 2.10.50"
8183
8184         # Create composite files with one component
8185         local dir=$DIR/$tdir
8186
8187         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8188         # Create composite files with three components
8189         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8190         # Create non-composite files
8191         createmany -o $dir/${tfile}- 10
8192
8193         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8194
8195         [[ $nfiles == 10 ]] ||
8196                 error "lfs find -E 1M found $nfiles != 10 files"
8197
8198         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8199         [[ $nfiles == 25 ]] ||
8200                 error "lfs find ! -E 1M found $nfiles != 25 files"
8201
8202         # All files have a component that starts at 0
8203         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8204         [[ $nfiles == 35 ]] ||
8205                 error "lfs find --component-start 0 - $nfiles != 35 files"
8206
8207         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8208         [[ $nfiles == 15 ]] ||
8209                 error "lfs find --component-start 2M - $nfiles != 15 files"
8210
8211         # All files created here have a componenet that does not starts at 2M
8212         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8213         [[ $nfiles == 35 ]] ||
8214                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8215
8216         # Find files with a specified number of components
8217         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8218         [[ $nfiles == 15 ]] ||
8219                 error "lfs find --component-count 3 - $nfiles != 15 files"
8220
8221         # Remember non-composite files have a component count of zero
8222         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8223         [[ $nfiles == 10 ]] ||
8224                 error "lfs find --component-count 0 - $nfiles != 10 files"
8225
8226         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8227         [[ $nfiles == 20 ]] ||
8228                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8229
8230         # All files have a flag called "init"
8231         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8232         [[ $nfiles == 35 ]] ||
8233                 error "lfs find --component-flags init - $nfiles != 35 files"
8234
8235         # Multi-component files will have a component not initialized
8236         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8237         [[ $nfiles == 15 ]] ||
8238                 error "lfs find !--component-flags init - $nfiles != 15 files"
8239
8240         rm -rf $dir
8241
8242 }
8243 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8244
8245 test_56ca() {
8246         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8247                 skip "Need MDS version at least 2.10.57"
8248
8249         local td=$DIR/$tdir
8250         local tf=$td/$tfile
8251         local dir
8252         local nfiles
8253         local cmd
8254         local i
8255         local j
8256
8257         # create mirrored directories and mirrored files
8258         mkdir $td || error "mkdir $td failed"
8259         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8260         createmany -o $tf- 10 || error "create $tf- failed"
8261
8262         for i in $(seq 2); do
8263                 dir=$td/dir$i
8264                 mkdir $dir || error "mkdir $dir failed"
8265                 $LFS mirror create -N$((3 + i)) $dir ||
8266                         error "create mirrored dir $dir failed"
8267                 createmany -o $dir/$tfile- 10 ||
8268                         error "create $dir/$tfile- failed"
8269         done
8270
8271         # change the states of some mirrored files
8272         echo foo > $tf-6
8273         for i in $(seq 2); do
8274                 dir=$td/dir$i
8275                 for j in $(seq 4 9); do
8276                         echo foo > $dir/$tfile-$j
8277                 done
8278         done
8279
8280         # find mirrored files with specific mirror count
8281         cmd="$LFS find --mirror-count 3 --type f $td"
8282         nfiles=$($cmd | wc -l)
8283         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8284
8285         cmd="$LFS find ! --mirror-count 3 --type f $td"
8286         nfiles=$($cmd | wc -l)
8287         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8288
8289         cmd="$LFS find --mirror-count +2 --type f $td"
8290         nfiles=$($cmd | wc -l)
8291         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8292
8293         cmd="$LFS find --mirror-count -6 --type f $td"
8294         nfiles=$($cmd | wc -l)
8295         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8296
8297         # find mirrored files with specific file state
8298         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8299         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8300
8301         cmd="$LFS find --mirror-state=ro --type f $td"
8302         nfiles=$($cmd | wc -l)
8303         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8304
8305         cmd="$LFS find ! --mirror-state=ro --type f $td"
8306         nfiles=$($cmd | wc -l)
8307         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8308
8309         cmd="$LFS find --mirror-state=wp --type f $td"
8310         nfiles=$($cmd | wc -l)
8311         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8312
8313         cmd="$LFS find ! --mirror-state=sp --type f $td"
8314         nfiles=$($cmd | wc -l)
8315         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8316 }
8317 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8318
8319 test_56da() { # LU-14179
8320         local path=$DIR/$tdir
8321
8322         test_mkdir $path
8323         cd $path
8324
8325         local longdir=$(str_repeat 'a' 255)
8326
8327         for i in {1..15}; do
8328                 path=$path/$longdir
8329                 test_mkdir $longdir
8330                 cd $longdir
8331         done
8332
8333         local len=${#path}
8334         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8335
8336         test_mkdir $lastdir
8337         cd $lastdir
8338         # PATH_MAX-1
8339         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8340
8341         # NAME_MAX
8342         touch $(str_repeat 'f' 255)
8343
8344         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8345                 error "lfs find reported an error"
8346
8347         rm -rf $DIR/$tdir
8348 }
8349 run_test 56da "test lfs find with long paths"
8350
8351 test_56ea() { #LU-10378
8352         local path=$DIR/$tdir
8353         local pool=$TESTNAME
8354
8355         # Create ost pool
8356         pool_add $pool || error "pool_add $pool failed"
8357         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8358                 error "adding targets to $pool failed"
8359
8360         # Set default pool on directory before creating file
8361         mkdir $path || error "mkdir $path failed"
8362         $LFS setstripe -p $pool $path ||
8363                 error "set OST pool on $pool failed"
8364         touch $path/$tfile || error "touch $path/$tfile failed"
8365
8366         # Compare basic file attributes from -printf and stat
8367         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8368         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8369
8370         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8371                 error "Attrs from lfs find and stat don't match"
8372
8373         # Compare Lustre attributes from lfs find and lfs getstripe
8374         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8375         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8376         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8377         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8378         local fpool=$($LFS getstripe --pool $path/$tfile)
8379         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8380
8381         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8382                 error "Attrs from lfs find and lfs getstripe don't match"
8383
8384         # Verify behavior for unknown escape/format sequences
8385         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8386
8387         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8388                 error "Escape/format codes don't match"
8389 }
8390 run_test 56ea "test lfs find -printf option"
8391
8392 test_57a() {
8393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8394         # note test will not do anything if MDS is not local
8395         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8396                 skip_env "ldiskfs only test"
8397         fi
8398         remote_mds_nodsh && skip "remote MDS with nodsh"
8399
8400         local MNTDEV="osd*.*MDT*.mntdev"
8401         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8402         [ -z "$DEV" ] && error "can't access $MNTDEV"
8403         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8404                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8405                         error "can't access $DEV"
8406                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8407                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8408                 rm $TMP/t57a.dump
8409         done
8410 }
8411 run_test 57a "verify MDS filesystem created with large inodes =="
8412
8413 test_57b() {
8414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8415         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8416                 skip_env "ldiskfs only test"
8417         fi
8418         remote_mds_nodsh && skip "remote MDS with nodsh"
8419
8420         local dir=$DIR/$tdir
8421         local filecount=100
8422         local file1=$dir/f1
8423         local fileN=$dir/f$filecount
8424
8425         rm -rf $dir || error "removing $dir"
8426         test_mkdir -c1 $dir
8427         local mdtidx=$($LFS getstripe -m $dir)
8428         local mdtname=MDT$(printf %04x $mdtidx)
8429         local facet=mds$((mdtidx + 1))
8430
8431         echo "mcreating $filecount files"
8432         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8433
8434         # verify that files do not have EAs yet
8435         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8436                 error "$file1 has an EA"
8437         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8438                 error "$fileN has an EA"
8439
8440         sync
8441         sleep 1
8442         df $dir  #make sure we get new statfs data
8443         local mdsfree=$(do_facet $facet \
8444                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8445         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8446         local file
8447
8448         echo "opening files to create objects/EAs"
8449         for file in $(seq -f $dir/f%g 1 $filecount); do
8450                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8451                         error "opening $file"
8452         done
8453
8454         # verify that files have EAs now
8455         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8456         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8457
8458         sleep 1  #make sure we get new statfs data
8459         df $dir
8460         local mdsfree2=$(do_facet $facet \
8461                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8462         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8463
8464         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8465                 if [ "$mdsfree" != "$mdsfree2" ]; then
8466                         error "MDC before $mdcfree != after $mdcfree2"
8467                 else
8468                         echo "MDC before $mdcfree != after $mdcfree2"
8469                         echo "unable to confirm if MDS has large inodes"
8470                 fi
8471         fi
8472         rm -rf $dir
8473 }
8474 run_test 57b "default LOV EAs are stored inside large inodes ==="
8475
8476 test_58() {
8477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8478         [ -z "$(which wiretest 2>/dev/null)" ] &&
8479                         skip_env "could not find wiretest"
8480
8481         wiretest
8482 }
8483 run_test 58 "verify cross-platform wire constants =============="
8484
8485 test_59() {
8486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8487
8488         echo "touch 130 files"
8489         createmany -o $DIR/f59- 130
8490         echo "rm 130 files"
8491         unlinkmany $DIR/f59- 130
8492         sync
8493         # wait for commitment of removal
8494         wait_delete_completed
8495 }
8496 run_test 59 "verify cancellation of llog records async ========="
8497
8498 TEST60_HEAD="test_60 run $RANDOM"
8499 test_60a() {
8500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8501         remote_mgs_nodsh && skip "remote MGS with nodsh"
8502         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8503                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8504                         skip_env "missing subtest run-llog.sh"
8505
8506         log "$TEST60_HEAD - from kernel mode"
8507         do_facet mgs "$LCTL dk > /dev/null"
8508         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8509         do_facet mgs $LCTL dk > $TMP/$tfile
8510
8511         # LU-6388: test llog_reader
8512         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8513         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8514         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8515                         skip_env "missing llog_reader"
8516         local fstype=$(facet_fstype mgs)
8517         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8518                 skip_env "Only for ldiskfs or zfs type mgs"
8519
8520         local mntpt=$(facet_mntpt mgs)
8521         local mgsdev=$(mgsdevname 1)
8522         local fid_list
8523         local fid
8524         local rec_list
8525         local rec
8526         local rec_type
8527         local obj_file
8528         local path
8529         local seq
8530         local oid
8531         local pass=true
8532
8533         #get fid and record list
8534         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8535                 tail -n 4))
8536         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8537                 tail -n 4))
8538         #remount mgs as ldiskfs or zfs type
8539         stop mgs || error "stop mgs failed"
8540         mount_fstype mgs || error "remount mgs failed"
8541         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8542                 fid=${fid_list[i]}
8543                 rec=${rec_list[i]}
8544                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8545                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8546                 oid=$((16#$oid))
8547
8548                 case $fstype in
8549                         ldiskfs )
8550                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8551                         zfs )
8552                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8553                 esac
8554                 echo "obj_file is $obj_file"
8555                 do_facet mgs $llog_reader $obj_file
8556
8557                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8558                         awk '{ print $3 }' | sed -e "s/^type=//g")
8559                 if [ $rec_type != $rec ]; then
8560                         echo "FAILED test_60a wrong record type $rec_type," \
8561                               "should be $rec"
8562                         pass=false
8563                         break
8564                 fi
8565
8566                 #check obj path if record type is LLOG_LOGID_MAGIC
8567                 if [ "$rec" == "1064553b" ]; then
8568                         path=$(do_facet mgs $llog_reader $obj_file |
8569                                 grep "path=" | awk '{ print $NF }' |
8570                                 sed -e "s/^path=//g")
8571                         if [ $obj_file != $mntpt/$path ]; then
8572                                 echo "FAILED test_60a wrong obj path" \
8573                                       "$montpt/$path, should be $obj_file"
8574                                 pass=false
8575                                 break
8576                         fi
8577                 fi
8578         done
8579         rm -f $TMP/$tfile
8580         #restart mgs before "error", otherwise it will block the next test
8581         stop mgs || error "stop mgs failed"
8582         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8583         $pass || error "test failed, see FAILED test_60a messages for specifics"
8584 }
8585 run_test 60a "llog_test run from kernel module and test llog_reader"
8586
8587 test_60b() { # bug 6411
8588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8589
8590         dmesg > $DIR/$tfile
8591         LLOG_COUNT=$(do_facet mgs dmesg |
8592                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8593                           /llog_[a-z]*.c:[0-9]/ {
8594                                 if (marker)
8595                                         from_marker++
8596                                 from_begin++
8597                           }
8598                           END {
8599                                 if (marker)
8600                                         print from_marker
8601                                 else
8602                                         print from_begin
8603                           }")
8604
8605         [[ $LLOG_COUNT -gt 120 ]] &&
8606                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8607 }
8608 run_test 60b "limit repeated messages from CERROR/CWARN"
8609
8610 test_60c() {
8611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8612
8613         echo "create 5000 files"
8614         createmany -o $DIR/f60c- 5000
8615 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8616         lctl set_param fail_loc=0x80000137
8617         unlinkmany $DIR/f60c- 5000
8618         lctl set_param fail_loc=0
8619 }
8620 run_test 60c "unlink file when mds full"
8621
8622 test_60d() {
8623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8624
8625         SAVEPRINTK=$(lctl get_param -n printk)
8626         # verify "lctl mark" is even working"
8627         MESSAGE="test message ID $RANDOM $$"
8628         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8629         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8630
8631         lctl set_param printk=0 || error "set lnet.printk failed"
8632         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8633         MESSAGE="new test message ID $RANDOM $$"
8634         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8635         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8636         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8637
8638         lctl set_param -n printk="$SAVEPRINTK"
8639 }
8640 run_test 60d "test printk console message masking"
8641
8642 test_60e() {
8643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8644         remote_mds_nodsh && skip "remote MDS with nodsh"
8645
8646         touch $DIR/$tfile
8647 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8648         do_facet mds1 lctl set_param fail_loc=0x15b
8649         rm $DIR/$tfile
8650 }
8651 run_test 60e "no space while new llog is being created"
8652
8653 test_60f() {
8654         local old_path=$($LCTL get_param -n debug_path)
8655
8656         stack_trap "$LCTL set_param debug_path=$old_path"
8657         stack_trap "rm -f $TMP/$tfile*"
8658         rm -f $TMP/$tfile* 2> /dev/null
8659         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8660         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8661         test_mkdir $DIR/$tdir
8662         # retry in case the open is cached and not released
8663         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8664                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8665                 sleep 0.1
8666         done
8667         ls $TMP/$tfile*
8668         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8669 }
8670 run_test 60f "change debug_path works"
8671
8672 test_60g() {
8673         local pid
8674         local i
8675
8676         test_mkdir -c $MDSCOUNT $DIR/$tdir
8677
8678         (
8679                 local index=0
8680                 while true; do
8681                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8682                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8683                                 2>/dev/null
8684                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8685                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8686                         index=$((index + 1))
8687                 done
8688         ) &
8689
8690         pid=$!
8691
8692         for i in {0..100}; do
8693                 # define OBD_FAIL_OSD_TXN_START    0x19a
8694                 local index=$((i % MDSCOUNT + 1))
8695
8696                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8697                         > /dev/null
8698                 sleep 0.01
8699         done
8700
8701         kill -9 $pid
8702
8703         for i in $(seq $MDSCOUNT); do
8704                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8705         done
8706
8707         mkdir $DIR/$tdir/new || error "mkdir failed"
8708         rmdir $DIR/$tdir/new || error "rmdir failed"
8709
8710         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8711                 -t namespace
8712         for i in $(seq $MDSCOUNT); do
8713                 wait_update_facet mds$i "$LCTL get_param -n \
8714                         mdd.$(facet_svc mds$i).lfsck_namespace |
8715                         awk '/^status/ { print \\\$2 }'" "completed"
8716         done
8717
8718         ls -R $DIR/$tdir
8719         rm -rf $DIR/$tdir || error "rmdir failed"
8720 }
8721 run_test 60g "transaction abort won't cause MDT hung"
8722
8723 test_60h() {
8724         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8725                 skip "Need MDS version at least 2.12.52"
8726         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8727
8728         local f
8729
8730         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8731         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8732         for fail_loc in 0x80000188 0x80000189; do
8733                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8734                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8735                         error "mkdir $dir-$fail_loc failed"
8736                 for i in {0..10}; do
8737                         # create may fail on missing stripe
8738                         echo $i > $DIR/$tdir-$fail_loc/$i
8739                 done
8740                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8741                         error "getdirstripe $tdir-$fail_loc failed"
8742                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8743                         error "migrate $tdir-$fail_loc failed"
8744                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8745                         error "getdirstripe $tdir-$fail_loc failed"
8746                 pushd $DIR/$tdir-$fail_loc
8747                 for f in *; do
8748                         echo $f | cmp $f - || error "$f data mismatch"
8749                 done
8750                 popd
8751                 rm -rf $DIR/$tdir-$fail_loc
8752         done
8753 }
8754 run_test 60h "striped directory with missing stripes can be accessed"
8755
8756 function t60i_load() {
8757         mkdir $DIR/$tdir
8758         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8759         $LCTL set_param fail_loc=0x131c fail_val=1
8760         for ((i=0; i<5000; i++)); do
8761                 touch $DIR/$tdir/f$i
8762         done
8763 }
8764
8765 test_60i() {
8766         changelog_register || error "changelog_register failed"
8767         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8768         changelog_users $SINGLEMDS | grep -q $cl_user ||
8769                 error "User $cl_user not found in changelog_users"
8770         changelog_chmask "ALL"
8771         t60i_load &
8772         local PID=$!
8773         for((i=0; i<100; i++)); do
8774                 changelog_dump >/dev/null ||
8775                         error "can't read changelog"
8776         done
8777         kill $PID
8778         wait $PID
8779         changelog_deregister || error "changelog_deregister failed"
8780         $LCTL set_param fail_loc=0
8781 }
8782 run_test 60i "llog: new record vs reader race"
8783
8784 test_61a() {
8785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8786
8787         f="$DIR/f61"
8788         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8789         cancel_lru_locks osc
8790         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8791         sync
8792 }
8793 run_test 61a "mmap() writes don't make sync hang ================"
8794
8795 test_61b() {
8796         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8797 }
8798 run_test 61b "mmap() of unstriped file is successful"
8799
8800 # bug 2330 - insufficient obd_match error checking causes LBUG
8801 test_62() {
8802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8803
8804         f="$DIR/f62"
8805         echo foo > $f
8806         cancel_lru_locks osc
8807         lctl set_param fail_loc=0x405
8808         cat $f && error "cat succeeded, expect -EIO"
8809         lctl set_param fail_loc=0
8810 }
8811 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8812 # match every page all of the time.
8813 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8814
8815 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8816 # Though this test is irrelevant anymore, it helped to reveal some
8817 # other grant bugs (LU-4482), let's keep it.
8818 test_63a() {   # was test_63
8819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8820
8821         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8822
8823         for i in `seq 10` ; do
8824                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8825                 sleep 5
8826                 kill $!
8827                 sleep 1
8828         done
8829
8830         rm -f $DIR/f63 || true
8831 }
8832 run_test 63a "Verify oig_wait interruption does not crash ======="
8833
8834 # bug 2248 - async write errors didn't return to application on sync
8835 # bug 3677 - async write errors left page locked
8836 test_63b() {
8837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8838
8839         debugsave
8840         lctl set_param debug=-1
8841
8842         # ensure we have a grant to do async writes
8843         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8844         rm $DIR/$tfile
8845
8846         sync    # sync lest earlier test intercept the fail_loc
8847
8848         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8849         lctl set_param fail_loc=0x80000406
8850         $MULTIOP $DIR/$tfile Owy && \
8851                 error "sync didn't return ENOMEM"
8852         sync; sleep 2; sync     # do a real sync this time to flush page
8853         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8854                 error "locked page left in cache after async error" || true
8855         debugrestore
8856 }
8857 run_test 63b "async write errors should be returned to fsync ==="
8858
8859 test_64a () {
8860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8861
8862         lfs df $DIR
8863         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8864 }
8865 run_test 64a "verify filter grant calculations (in kernel) ====="
8866
8867 test_64b () {
8868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8869
8870         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8871 }
8872 run_test 64b "check out-of-space detection on client"
8873
8874 test_64c() {
8875         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8876 }
8877 run_test 64c "verify grant shrink"
8878
8879 import_param() {
8880         local tgt=$1
8881         local param=$2
8882
8883         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8884 }
8885
8886 # this does exactly what osc_request.c:osc_announce_cached() does in
8887 # order to calculate max amount of grants to ask from server
8888 want_grant() {
8889         local tgt=$1
8890
8891         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8892         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8893
8894         ((rpc_in_flight++));
8895         nrpages=$((nrpages * rpc_in_flight))
8896
8897         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8898
8899         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8900
8901         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8902         local undirty=$((nrpages * PAGE_SIZE))
8903
8904         local max_extent_pages
8905         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8906         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8907         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8908         local grant_extent_tax
8909         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8910
8911         undirty=$((undirty + nrextents * grant_extent_tax))
8912
8913         echo $undirty
8914 }
8915
8916 # this is size of unit for grant allocation. It should be equal to
8917 # what tgt_grant.c:tgt_grant_chunk() calculates
8918 grant_chunk() {
8919         local tgt=$1
8920         local max_brw_size
8921         local grant_extent_tax
8922
8923         max_brw_size=$(import_param $tgt max_brw_size)
8924
8925         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8926
8927         echo $(((max_brw_size + grant_extent_tax) * 2))
8928 }
8929
8930 test_64d() {
8931         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8932                 skip "OST < 2.10.55 doesn't limit grants enough"
8933
8934         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8935
8936         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8937                 skip "no grant_param connect flag"
8938
8939         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8940
8941         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8942         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8943
8944
8945         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8946         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8947
8948         $LFS setstripe $DIR/$tfile -i 0 -c 1
8949         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8950         ddpid=$!
8951
8952         while kill -0 $ddpid; do
8953                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8954
8955                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8956                         kill $ddpid
8957                         error "cur_grant $cur_grant > $max_cur_granted"
8958                 fi
8959
8960                 sleep 1
8961         done
8962 }
8963 run_test 64d "check grant limit exceed"
8964
8965 check_grants() {
8966         local tgt=$1
8967         local expected=$2
8968         local msg=$3
8969         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8970
8971         ((cur_grants == expected)) ||
8972                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8973 }
8974
8975 round_up_p2() {
8976         echo $((($1 + $2 - 1) & ~($2 - 1)))
8977 }
8978
8979 test_64e() {
8980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8981         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8982                 skip "Need OSS version at least 2.11.56"
8983
8984         # Remount client to reset grant
8985         remount_client $MOUNT || error "failed to remount client"
8986         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8987
8988         local init_grants=$(import_param $osc_tgt initial_grant)
8989
8990         check_grants $osc_tgt $init_grants "init grants"
8991
8992         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8993         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8994         local gbs=$(import_param $osc_tgt grant_block_size)
8995
8996         # write random number of bytes from max_brw_size / 4 to max_brw_size
8997         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8998         # align for direct io
8999         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9000         # round to grant consumption unit
9001         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9002
9003         local grants=$((wb_round_up + extent_tax))
9004
9005         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9006
9007         # define OBD_FAIL_TGT_NO_GRANT 0x725
9008         # make the server not grant more back
9009         do_facet ost1 $LCTL set_param fail_loc=0x725
9010         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9011
9012         do_facet ost1 $LCTL set_param fail_loc=0
9013
9014         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9015
9016         rm -f $DIR/$tfile || error "rm failed"
9017
9018         # Remount client to reset grant
9019         remount_client $MOUNT || error "failed to remount client"
9020         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9021
9022         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9023
9024         # define OBD_FAIL_TGT_NO_GRANT 0x725
9025         # make the server not grant more back
9026         do_facet ost1 $LCTL set_param fail_loc=0x725
9027         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9028         do_facet ost1 $LCTL set_param fail_loc=0
9029
9030         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9031 }
9032 run_test 64e "check grant consumption (no grant allocation)"
9033
9034 test_64f() {
9035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9036
9037         # Remount client to reset grant
9038         remount_client $MOUNT || error "failed to remount client"
9039         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9040
9041         local init_grants=$(import_param $osc_tgt initial_grant)
9042         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9043         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9044         local gbs=$(import_param $osc_tgt grant_block_size)
9045         local chunk=$(grant_chunk $osc_tgt)
9046
9047         # write random number of bytes from max_brw_size / 4 to max_brw_size
9048         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9049         # align for direct io
9050         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9051         # round to grant consumption unit
9052         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9053
9054         local grants=$((wb_round_up + extent_tax))
9055
9056         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9057         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9058                 error "error writing to $DIR/$tfile"
9059
9060         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9061                 "direct io with grant allocation"
9062
9063         rm -f $DIR/$tfile || error "rm failed"
9064
9065         # Remount client to reset grant
9066         remount_client $MOUNT || error "failed to remount client"
9067         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9068
9069         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9070
9071         local cmd="oO_WRONLY:w${write_bytes}_yc"
9072
9073         $MULTIOP $DIR/$tfile $cmd &
9074         MULTIPID=$!
9075         sleep 1
9076
9077         check_grants $osc_tgt $((init_grants - grants)) \
9078                 "buffered io, not write rpc"
9079
9080         kill -USR1 $MULTIPID
9081         wait
9082
9083         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9084                 "buffered io, one RPC"
9085 }
9086 run_test 64f "check grant consumption (with grant allocation)"
9087
9088 test_64g() {
9089         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9090                 skip "Need MDS version at least 2.14.56"
9091
9092         local mdts=$(comma_list $(mdts_nodes))
9093
9094         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9095                         tr '\n' ' ')
9096         stack_trap "$LCTL set_param $old"
9097
9098         # generate dirty pages and increase dirty granted on MDT
9099         stack_trap "rm -f $DIR/$tfile-*"
9100         for (( i = 0; i < 10; i++)); do
9101                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9102                         error "can't set stripe"
9103                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9104                         error "can't dd"
9105                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9106                         $LFS getstripe $DIR/$tfile-$i
9107                         error "not DoM file"
9108                 }
9109         done
9110
9111         # flush dirty pages
9112         sync
9113
9114         # wait until grant shrink reset grant dirty on MDTs
9115         for ((i = 0; i < 120; i++)); do
9116                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9117                         awk '{sum=sum+$1} END {print sum}')
9118                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9119                 echo "$grant_dirty grants, $vm_dirty pages"
9120                 (( grant_dirty + vm_dirty == 0 )) && break
9121                 (( i == 3 )) && sync &&
9122                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9123                 sleep 1
9124         done
9125
9126         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9127                 awk '{sum=sum+$1} END {print sum}')
9128         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9129 }
9130 run_test 64g "grant shrink on MDT"
9131
9132 test_64h() {
9133         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9134                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9135
9136         local instance=$($LFS getname -i $DIR)
9137         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9138         local num_exps=$(do_facet ost1 \
9139             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9140         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9141         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9142         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9143
9144         # 10MiB is for file to be written, max_brw_size * 16 *
9145         # num_exps is space reserve so that tgt_grant_shrink() decided
9146         # to not shrink
9147         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9148         (( avail * 1024 < expect )) &&
9149                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9150
9151         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9152         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9153         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9154         $LCTL set_param osc.*OST0000*.grant_shrink=1
9155         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9156
9157         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9158         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9159
9160         # drop cache so that coming read would do rpc
9161         cancel_lru_locks osc
9162
9163         # shrink interval is set to 10, pause for 7 seconds so that
9164         # grant thread did not wake up yet but coming read entered
9165         # shrink mode for rpc (osc_should_shrink_grant())
9166         sleep 7
9167
9168         declare -a cur_grant_bytes
9169         declare -a tot_granted
9170         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9171         tot_granted[0]=$(do_facet ost1 \
9172             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9173
9174         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9175
9176         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9177         tot_granted[1]=$(do_facet ost1 \
9178             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9179
9180         # grant change should be equal on both sides
9181         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9182                 tot_granted[0] - tot_granted[1])) ||
9183                 error "grant change mismatch, "                                \
9184                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9185                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9186 }
9187 run_test 64h "grant shrink on read"
9188
9189 test_64i() {
9190         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9191                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9192
9193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9194         remote_ost_nodsh && skip "remote OSTs with nodsh"
9195
9196         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9197
9198         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9199
9200         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9201         local instance=$($LFS getname -i $DIR)
9202
9203         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9204         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9205
9206         # shrink grants and simulate rpc loss
9207         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9208         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9209         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9210
9211         fail ost1
9212
9213         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9214
9215         local testid=$(echo $TESTNAME | tr '_' ' ')
9216
9217         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9218                 grep "GRANT, real grant" &&
9219                 error "client has more grants then it owns" || true
9220 }
9221 run_test 64i "shrink on reconnect"
9222
9223 # bug 1414 - set/get directories' stripe info
9224 test_65a() {
9225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9226
9227         test_mkdir $DIR/$tdir
9228         touch $DIR/$tdir/f1
9229         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9230 }
9231 run_test 65a "directory with no stripe info"
9232
9233 test_65b() {
9234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9235
9236         test_mkdir $DIR/$tdir
9237         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9238
9239         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9240                                                 error "setstripe"
9241         touch $DIR/$tdir/f2
9242         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9243 }
9244 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9245
9246 test_65c() {
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9249
9250         test_mkdir $DIR/$tdir
9251         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9252
9253         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9254                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9255         touch $DIR/$tdir/f3
9256         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9257 }
9258 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9259
9260 test_65d() {
9261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9262
9263         test_mkdir $DIR/$tdir
9264         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9265         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9266
9267         if [[ $STRIPECOUNT -le 0 ]]; then
9268                 sc=1
9269         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9270                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9271                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9272         else
9273                 sc=$(($STRIPECOUNT - 1))
9274         fi
9275         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9276         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9277         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9278                 error "lverify failed"
9279 }
9280 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9281
9282 test_65e() {
9283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9284
9285         test_mkdir $DIR/$tdir
9286
9287         $LFS setstripe $DIR/$tdir || error "setstripe"
9288         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9289                                         error "no stripe info failed"
9290         touch $DIR/$tdir/f6
9291         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9292 }
9293 run_test 65e "directory setstripe defaults"
9294
9295 test_65f() {
9296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9297
9298         test_mkdir $DIR/${tdir}f
9299         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9300                 error "setstripe succeeded" || true
9301 }
9302 run_test 65f "dir setstripe permission (should return error) ==="
9303
9304 test_65g() {
9305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9306
9307         test_mkdir $DIR/$tdir
9308         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9309
9310         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9311                 error "setstripe -S failed"
9312         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9313         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9314                 error "delete default stripe failed"
9315 }
9316 run_test 65g "directory setstripe -d"
9317
9318 test_65h() {
9319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9320
9321         test_mkdir $DIR/$tdir
9322         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9323
9324         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9325                 error "setstripe -S failed"
9326         test_mkdir $DIR/$tdir/dd1
9327         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9328                 error "stripe info inherit failed"
9329 }
9330 run_test 65h "directory stripe info inherit ===================="
9331
9332 test_65i() {
9333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9334
9335         save_layout_restore_at_exit $MOUNT
9336
9337         # bug6367: set non-default striping on root directory
9338         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9339
9340         # bug12836: getstripe on -1 default directory striping
9341         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9342
9343         # bug12836: getstripe -v on -1 default directory striping
9344         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9345
9346         # bug12836: new find on -1 default directory striping
9347         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9348 }
9349 run_test 65i "various tests to set root directory striping"
9350
9351 test_65j() { # bug6367
9352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9353
9354         sync; sleep 1
9355
9356         # if we aren't already remounting for each test, do so for this test
9357         if [ "$I_MOUNTED" = "yes" ]; then
9358                 cleanup || error "failed to unmount"
9359                 setup
9360         fi
9361
9362         save_layout_restore_at_exit $MOUNT
9363
9364         $LFS setstripe -d $MOUNT || error "setstripe failed"
9365 }
9366 run_test 65j "set default striping on root directory (bug 6367)="
9367
9368 cleanup_65k() {
9369         rm -rf $DIR/$tdir
9370         wait_delete_completed
9371         do_facet $SINGLEMDS "lctl set_param -n \
9372                 osp.$ost*MDT0000.max_create_count=$max_count"
9373         do_facet $SINGLEMDS "lctl set_param -n \
9374                 osp.$ost*MDT0000.create_count=$count"
9375         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9376         echo $INACTIVE_OSC "is Activate"
9377
9378         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9379 }
9380
9381 test_65k() { # bug11679
9382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9384         remote_mds_nodsh && skip "remote MDS with nodsh"
9385
9386         local disable_precreate=true
9387         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9388                 disable_precreate=false
9389
9390         echo "Check OST status: "
9391         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9392                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9393
9394         for OSC in $MDS_OSCS; do
9395                 echo $OSC "is active"
9396                 do_facet $SINGLEMDS lctl --device %$OSC activate
9397         done
9398
9399         for INACTIVE_OSC in $MDS_OSCS; do
9400                 local ost=$(osc_to_ost $INACTIVE_OSC)
9401                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9402                                lov.*md*.target_obd |
9403                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9404
9405                 mkdir -p $DIR/$tdir
9406                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9407                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9408
9409                 echo "Deactivate: " $INACTIVE_OSC
9410                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9411
9412                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9413                               osp.$ost*MDT0000.create_count")
9414                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9415                                   osp.$ost*MDT0000.max_create_count")
9416                 $disable_precreate &&
9417                         do_facet $SINGLEMDS "lctl set_param -n \
9418                                 osp.$ost*MDT0000.max_create_count=0"
9419
9420                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9421                         [ -f $DIR/$tdir/$idx ] && continue
9422                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9423                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9424                                 { cleanup_65k;
9425                                   error "setstripe $idx should succeed"; }
9426                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9427                 done
9428                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9429                 rmdir $DIR/$tdir
9430
9431                 do_facet $SINGLEMDS "lctl set_param -n \
9432                         osp.$ost*MDT0000.max_create_count=$max_count"
9433                 do_facet $SINGLEMDS "lctl set_param -n \
9434                         osp.$ost*MDT0000.create_count=$count"
9435                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9436                 echo $INACTIVE_OSC "is Activate"
9437
9438                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9439         done
9440 }
9441 run_test 65k "validate manual striping works properly with deactivated OSCs"
9442
9443 test_65l() { # bug 12836
9444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9445
9446         test_mkdir -p $DIR/$tdir/test_dir
9447         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9448         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9449 }
9450 run_test 65l "lfs find on -1 stripe dir ========================"
9451
9452 test_65m() {
9453         local layout=$(save_layout $MOUNT)
9454         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9455                 restore_layout $MOUNT $layout
9456                 error "setstripe should fail by non-root users"
9457         }
9458         true
9459 }
9460 run_test 65m "normal user can't set filesystem default stripe"
9461
9462 test_65n() {
9463         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9464         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9465                 skip "Need MDS version at least 2.12.50"
9466         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9467
9468         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9469         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9470         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9471
9472         save_layout_restore_at_exit $MOUNT
9473
9474         # new subdirectory under root directory should not inherit
9475         # the default layout from root
9476         local dir1=$MOUNT/$tdir-1
9477         mkdir $dir1 || error "mkdir $dir1 failed"
9478         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9479                 error "$dir1 shouldn't have LOV EA"
9480
9481         # delete the default layout on root directory
9482         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9483
9484         local dir2=$MOUNT/$tdir-2
9485         mkdir $dir2 || error "mkdir $dir2 failed"
9486         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9487                 error "$dir2 shouldn't have LOV EA"
9488
9489         # set a new striping pattern on root directory
9490         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9491         local new_def_stripe_size=$((def_stripe_size * 2))
9492         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9493                 error "set stripe size on $MOUNT failed"
9494
9495         # new file created in $dir2 should inherit the new stripe size from
9496         # the filesystem default
9497         local file2=$dir2/$tfile-2
9498         touch $file2 || error "touch $file2 failed"
9499
9500         local file2_stripe_size=$($LFS getstripe -S $file2)
9501         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9502         {
9503                 echo "file2_stripe_size: '$file2_stripe_size'"
9504                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9505                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9506         }
9507
9508         local dir3=$MOUNT/$tdir-3
9509         mkdir $dir3 || error "mkdir $dir3 failed"
9510         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9511         # the root layout, which is the actual default layout that will be used
9512         # when new files are created in $dir3.
9513         local dir3_layout=$(get_layout_param $dir3)
9514         local root_dir_layout=$(get_layout_param $MOUNT)
9515         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9516         {
9517                 echo "dir3_layout: '$dir3_layout'"
9518                 echo "root_dir_layout: '$root_dir_layout'"
9519                 error "$dir3 should show the default layout from $MOUNT"
9520         }
9521
9522         # set OST pool on root directory
9523         local pool=$TESTNAME
9524         pool_add $pool || error "add $pool failed"
9525         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9526                 error "add targets to $pool failed"
9527
9528         $LFS setstripe -p $pool $MOUNT ||
9529                 error "set OST pool on $MOUNT failed"
9530
9531         # new file created in $dir3 should inherit the pool from
9532         # the filesystem default
9533         local file3=$dir3/$tfile-3
9534         touch $file3 || error "touch $file3 failed"
9535
9536         local file3_pool=$($LFS getstripe -p $file3)
9537         [[ "$file3_pool" = "$pool" ]] ||
9538                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9539
9540         local dir4=$MOUNT/$tdir-4
9541         mkdir $dir4 || error "mkdir $dir4 failed"
9542         local dir4_layout=$(get_layout_param $dir4)
9543         root_dir_layout=$(get_layout_param $MOUNT)
9544         echo "$LFS getstripe -d $dir4"
9545         $LFS getstripe -d $dir4
9546         echo "$LFS getstripe -d $MOUNT"
9547         $LFS getstripe -d $MOUNT
9548         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9549         {
9550                 echo "dir4_layout: '$dir4_layout'"
9551                 echo "root_dir_layout: '$root_dir_layout'"
9552                 error "$dir4 should show the default layout from $MOUNT"
9553         }
9554
9555         # new file created in $dir4 should inherit the pool from
9556         # the filesystem default
9557         local file4=$dir4/$tfile-4
9558         touch $file4 || error "touch $file4 failed"
9559
9560         local file4_pool=$($LFS getstripe -p $file4)
9561         [[ "$file4_pool" = "$pool" ]] ||
9562                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9563
9564         # new subdirectory under non-root directory should inherit
9565         # the default layout from its parent directory
9566         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9567                 error "set directory layout on $dir4 failed"
9568
9569         local dir5=$dir4/$tdir-5
9570         mkdir $dir5 || error "mkdir $dir5 failed"
9571
9572         dir4_layout=$(get_layout_param $dir4)
9573         local dir5_layout=$(get_layout_param $dir5)
9574         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9575         {
9576                 echo "dir4_layout: '$dir4_layout'"
9577                 echo "dir5_layout: '$dir5_layout'"
9578                 error "$dir5 should inherit the default layout from $dir4"
9579         }
9580
9581         # though subdir under ROOT doesn't inherit default layout, but
9582         # its sub dir/file should be created with default layout.
9583         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9584         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9585                 skip "Need MDS version at least 2.12.59"
9586
9587         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9588         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9589         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9590
9591         if [ $default_lmv_hash == "none" ]; then
9592                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9593         else
9594                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9595                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9596         fi
9597
9598         $LFS setdirstripe -D -c 2 $MOUNT ||
9599                 error "setdirstripe -D -c 2 failed"
9600         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9601         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9602         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9603
9604         # $dir4 layout includes pool
9605         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9606         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9607                 error "pool lost on setstripe"
9608         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9609         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9610                 error "pool lost on compound layout setstripe"
9611 }
9612 run_test 65n "don't inherit default layout from root for new subdirectories"
9613
9614 # bug 2543 - update blocks count on client
9615 test_66() {
9616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9617
9618         COUNT=${COUNT:-8}
9619         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9620         sync; sync_all_data; sync; sync_all_data
9621         cancel_lru_locks osc
9622         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9623         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9624 }
9625 run_test 66 "update inode blocks count on client ==============="
9626
9627 meminfo() {
9628         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9629 }
9630
9631 swap_used() {
9632         swapon -s | awk '($1 == "'$1'") { print $4 }'
9633 }
9634
9635 # bug5265, obdfilter oa2dentry return -ENOENT
9636 # #define OBD_FAIL_SRV_ENOENT 0x217
9637 test_69() {
9638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9639         remote_ost_nodsh && skip "remote OST with nodsh"
9640
9641         f="$DIR/$tfile"
9642         $LFS setstripe -c 1 -i 0 $f
9643
9644         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9645
9646         do_facet ost1 lctl set_param fail_loc=0x217
9647         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9648         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9649
9650         do_facet ost1 lctl set_param fail_loc=0
9651         $DIRECTIO write $f 0 2 || error "write error"
9652
9653         cancel_lru_locks osc
9654         $DIRECTIO read $f 0 1 || error "read error"
9655
9656         do_facet ost1 lctl set_param fail_loc=0x217
9657         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9658
9659         do_facet ost1 lctl set_param fail_loc=0
9660         rm -f $f
9661 }
9662 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9663
9664 test_71() {
9665         test_mkdir $DIR/$tdir
9666         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9667         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9668 }
9669 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9670
9671 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9673         [ "$RUNAS_ID" = "$UID" ] &&
9674                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9675         # Check that testing environment is properly set up. Skip if not
9676         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9677                 skip_env "User $RUNAS_ID does not exist - skipping"
9678
9679         touch $DIR/$tfile
9680         chmod 777 $DIR/$tfile
9681         chmod ug+s $DIR/$tfile
9682         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9683                 error "$RUNAS dd $DIR/$tfile failed"
9684         # See if we are still setuid/sgid
9685         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9686                 error "S/gid is not dropped on write"
9687         # Now test that MDS is updated too
9688         cancel_lru_locks mdc
9689         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9690                 error "S/gid is not dropped on MDS"
9691         rm -f $DIR/$tfile
9692 }
9693 run_test 72a "Test that remove suid works properly (bug5695) ===="
9694
9695 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9696         local perm
9697
9698         [ "$RUNAS_ID" = "$UID" ] &&
9699                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9700         [ "$RUNAS_ID" -eq 0 ] &&
9701                 skip_env "RUNAS_ID = 0 -- skipping"
9702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9703         # Check that testing environment is properly set up. Skip if not
9704         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9705                 skip_env "User $RUNAS_ID does not exist - skipping"
9706
9707         touch $DIR/${tfile}-f{g,u}
9708         test_mkdir $DIR/${tfile}-dg
9709         test_mkdir $DIR/${tfile}-du
9710         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9711         chmod g+s $DIR/${tfile}-{f,d}g
9712         chmod u+s $DIR/${tfile}-{f,d}u
9713         for perm in 777 2777 4777; do
9714                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9715                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9716                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9717                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9718         done
9719         true
9720 }
9721 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9722
9723 # bug 3462 - multiple simultaneous MDC requests
9724 test_73() {
9725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9726
9727         test_mkdir $DIR/d73-1
9728         test_mkdir $DIR/d73-2
9729         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9730         pid1=$!
9731
9732         lctl set_param fail_loc=0x80000129
9733         $MULTIOP $DIR/d73-1/f73-2 Oc &
9734         sleep 1
9735         lctl set_param fail_loc=0
9736
9737         $MULTIOP $DIR/d73-2/f73-3 Oc &
9738         pid3=$!
9739
9740         kill -USR1 $pid1
9741         wait $pid1 || return 1
9742
9743         sleep 25
9744
9745         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9746         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9747         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9748
9749         rm -rf $DIR/d73-*
9750 }
9751 run_test 73 "multiple MDC requests (should not deadlock)"
9752
9753 test_74a() { # bug 6149, 6184
9754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9755
9756         touch $DIR/f74a
9757         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9758         #
9759         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9760         # will spin in a tight reconnection loop
9761         $LCTL set_param fail_loc=0x8000030e
9762         # get any lock that won't be difficult - lookup works.
9763         ls $DIR/f74a
9764         $LCTL set_param fail_loc=0
9765         rm -f $DIR/f74a
9766         true
9767 }
9768 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9769
9770 test_74b() { # bug 13310
9771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9772
9773         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9774         #
9775         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9776         # will spin in a tight reconnection loop
9777         $LCTL set_param fail_loc=0x8000030e
9778         # get a "difficult" lock
9779         touch $DIR/f74b
9780         $LCTL set_param fail_loc=0
9781         rm -f $DIR/f74b
9782         true
9783 }
9784 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9785
9786 test_74c() {
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788
9789         #define OBD_FAIL_LDLM_NEW_LOCK
9790         $LCTL set_param fail_loc=0x319
9791         touch $DIR/$tfile && error "touch successful"
9792         $LCTL set_param fail_loc=0
9793         true
9794 }
9795 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9796
9797 slab_lic=/sys/kernel/slab/lustre_inode_cache
9798 num_objects() {
9799         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9800         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9801                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9802 }
9803
9804 test_76a() { # Now for b=20433, added originally in b=1443
9805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9806
9807         cancel_lru_locks osc
9808         # there may be some slab objects cached per core
9809         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9810         local before=$(num_objects)
9811         local count=$((512 * cpus))
9812         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9813         local margin=$((count / 10))
9814         if [[ -f $slab_lic/aliases ]]; then
9815                 local aliases=$(cat $slab_lic/aliases)
9816                 (( aliases > 0 )) && margin=$((margin * aliases))
9817         fi
9818
9819         echo "before slab objects: $before"
9820         for i in $(seq $count); do
9821                 touch $DIR/$tfile
9822                 rm -f $DIR/$tfile
9823         done
9824         cancel_lru_locks osc
9825         local after=$(num_objects)
9826         echo "created: $count, after slab objects: $after"
9827         # shared slab counts are not very accurate, allow significant margin
9828         # the main goal is that the cache growth is not permanently > $count
9829         while (( after > before + margin )); do
9830                 sleep 1
9831                 after=$(num_objects)
9832                 wait=$((wait + 1))
9833                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9834                 if (( wait > 60 )); then
9835                         error "inode slab grew from $before+$margin to $after"
9836                 fi
9837         done
9838 }
9839 run_test 76a "confirm clients recycle inodes properly ===="
9840
9841 test_76b() {
9842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9843         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9844
9845         local count=512
9846         local before=$(num_objects)
9847
9848         for i in $(seq $count); do
9849                 mkdir $DIR/$tdir
9850                 rmdir $DIR/$tdir
9851         done
9852
9853         local after=$(num_objects)
9854         local wait=0
9855
9856         while (( after > before )); do
9857                 sleep 1
9858                 after=$(num_objects)
9859                 wait=$((wait + 1))
9860                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9861                 if (( wait > 60 )); then
9862                         error "inode slab grew from $before to $after"
9863                 fi
9864         done
9865
9866         echo "slab objects before: $before, after: $after"
9867 }
9868 run_test 76b "confirm clients recycle directory inodes properly ===="
9869
9870 export ORIG_CSUM=""
9871 set_checksums()
9872 {
9873         # Note: in sptlrpc modes which enable its own bulk checksum, the
9874         # original crc32_le bulk checksum will be automatically disabled,
9875         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9876         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9877         # In this case set_checksums() will not be no-op, because sptlrpc
9878         # bulk checksum will be enabled all through the test.
9879
9880         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9881         lctl set_param -n osc.*.checksums $1
9882         return 0
9883 }
9884
9885 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9886                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9887 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9888                              tr -d [] | head -n1)}
9889 set_checksum_type()
9890 {
9891         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9892         rc=$?
9893         log "set checksum type to $1, rc = $rc"
9894         return $rc
9895 }
9896
9897 get_osc_checksum_type()
9898 {
9899         # arugment 1: OST name, like OST0000
9900         ost=$1
9901         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9902                         sed 's/.*\[\(.*\)\].*/\1/g')
9903         rc=$?
9904         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9905         echo $checksum_type
9906 }
9907
9908 F77_TMP=$TMP/f77-temp
9909 F77SZ=8
9910 setup_f77() {
9911         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9912                 error "error writing to $F77_TMP"
9913 }
9914
9915 test_77a() { # bug 10889
9916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9917         $GSS && skip_env "could not run with gss"
9918
9919         [ ! -f $F77_TMP ] && setup_f77
9920         set_checksums 1
9921         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9922         set_checksums 0
9923         rm -f $DIR/$tfile
9924 }
9925 run_test 77a "normal checksum read/write operation"
9926
9927 test_77b() { # bug 10889
9928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9929         $GSS && skip_env "could not run with gss"
9930
9931         [ ! -f $F77_TMP ] && setup_f77
9932         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9933         $LCTL set_param fail_loc=0x80000409
9934         set_checksums 1
9935
9936         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9937                 error "dd error: $?"
9938         $LCTL set_param fail_loc=0
9939
9940         for algo in $CKSUM_TYPES; do
9941                 cancel_lru_locks osc
9942                 set_checksum_type $algo
9943                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9944                 $LCTL set_param fail_loc=0x80000408
9945                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9946                 $LCTL set_param fail_loc=0
9947         done
9948         set_checksums 0
9949         set_checksum_type $ORIG_CSUM_TYPE
9950         rm -f $DIR/$tfile
9951 }
9952 run_test 77b "checksum error on client write, read"
9953
9954 cleanup_77c() {
9955         trap 0
9956         set_checksums 0
9957         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9958         $check_ost &&
9959                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9960         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9961         $check_ost && [ -n "$ost_file_prefix" ] &&
9962                 do_facet ost1 rm -f ${ost_file_prefix}\*
9963 }
9964
9965 test_77c() {
9966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9967         $GSS && skip_env "could not run with gss"
9968         remote_ost_nodsh && skip "remote OST with nodsh"
9969
9970         local bad1
9971         local osc_file_prefix
9972         local osc_file
9973         local check_ost=false
9974         local ost_file_prefix
9975         local ost_file
9976         local orig_cksum
9977         local dump_cksum
9978         local fid
9979
9980         # ensure corruption will occur on first OSS/OST
9981         $LFS setstripe -i 0 $DIR/$tfile
9982
9983         [ ! -f $F77_TMP ] && setup_f77
9984         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9985                 error "dd write error: $?"
9986         fid=$($LFS path2fid $DIR/$tfile)
9987
9988         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9989         then
9990                 check_ost=true
9991                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9992                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9993         else
9994                 echo "OSS do not support bulk pages dump upon error"
9995         fi
9996
9997         osc_file_prefix=$($LCTL get_param -n debug_path)
9998         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9999
10000         trap cleanup_77c EXIT
10001
10002         set_checksums 1
10003         # enable bulk pages dump upon error on Client
10004         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10005         # enable bulk pages dump upon error on OSS
10006         $check_ost &&
10007                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10008
10009         # flush Client cache to allow next read to reach OSS
10010         cancel_lru_locks osc
10011
10012         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10013         $LCTL set_param fail_loc=0x80000408
10014         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10015         $LCTL set_param fail_loc=0
10016
10017         rm -f $DIR/$tfile
10018
10019         # check cksum dump on Client
10020         osc_file=$(ls ${osc_file_prefix}*)
10021         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10022         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10023         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10024         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10025         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10026                      cksum)
10027         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10028         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10029                 error "dump content does not match on Client"
10030
10031         $check_ost || skip "No need to check cksum dump on OSS"
10032
10033         # check cksum dump on OSS
10034         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10035         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10036         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10037         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10038         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10039                 error "dump content does not match on OSS"
10040
10041         cleanup_77c
10042 }
10043 run_test 77c "checksum error on client read with debug"
10044
10045 test_77d() { # bug 10889
10046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10047         $GSS && skip_env "could not run with gss"
10048
10049         stack_trap "rm -f $DIR/$tfile"
10050         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10051         $LCTL set_param fail_loc=0x80000409
10052         set_checksums 1
10053         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10054                 error "direct write: rc=$?"
10055         $LCTL set_param fail_loc=0
10056         set_checksums 0
10057
10058         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10059         $LCTL set_param fail_loc=0x80000408
10060         set_checksums 1
10061         cancel_lru_locks osc
10062         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10063                 error "direct read: rc=$?"
10064         $LCTL set_param fail_loc=0
10065         set_checksums 0
10066 }
10067 run_test 77d "checksum error on OST direct write, read"
10068
10069 test_77f() { # bug 10889
10070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10071         $GSS && skip_env "could not run with gss"
10072
10073         set_checksums 1
10074         stack_trap "rm -f $DIR/$tfile"
10075         for algo in $CKSUM_TYPES; do
10076                 cancel_lru_locks osc
10077                 set_checksum_type $algo
10078                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10079                 $LCTL set_param fail_loc=0x409
10080                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10081                         error "direct write succeeded"
10082                 $LCTL set_param fail_loc=0
10083         done
10084         set_checksum_type $ORIG_CSUM_TYPE
10085         set_checksums 0
10086 }
10087 run_test 77f "repeat checksum error on write (expect error)"
10088
10089 test_77g() { # bug 10889
10090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10091         $GSS && skip_env "could not run with gss"
10092         remote_ost_nodsh && skip "remote OST with nodsh"
10093
10094         [ ! -f $F77_TMP ] && setup_f77
10095
10096         local file=$DIR/$tfile
10097         stack_trap "rm -f $file" EXIT
10098
10099         $LFS setstripe -c 1 -i 0 $file
10100         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10101         do_facet ost1 lctl set_param fail_loc=0x8000021a
10102         set_checksums 1
10103         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10104                 error "write error: rc=$?"
10105         do_facet ost1 lctl set_param fail_loc=0
10106         set_checksums 0
10107
10108         cancel_lru_locks osc
10109         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10110         do_facet ost1 lctl set_param fail_loc=0x8000021b
10111         set_checksums 1
10112         cmp $F77_TMP $file || error "file compare failed"
10113         do_facet ost1 lctl set_param fail_loc=0
10114         set_checksums 0
10115 }
10116 run_test 77g "checksum error on OST write, read"
10117
10118 test_77k() { # LU-10906
10119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10120         $GSS && skip_env "could not run with gss"
10121
10122         local cksum_param="osc.$FSNAME*.checksums"
10123         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10124         local checksum
10125         local i
10126
10127         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10128         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10129         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10130
10131         for i in 0 1; do
10132                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10133                         error "failed to set checksum=$i on MGS"
10134                 wait_update $HOSTNAME "$get_checksum" $i
10135                 #remount
10136                 echo "remount client, checksum should be $i"
10137                 remount_client $MOUNT || error "failed to remount client"
10138                 checksum=$(eval $get_checksum)
10139                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10140         done
10141         # remove persistent param to avoid races with checksum mountopt below
10142         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10143                 error "failed to delete checksum on MGS"
10144
10145         for opt in "checksum" "nochecksum"; do
10146                 #remount with mount option
10147                 echo "remount client with option $opt, checksum should be $i"
10148                 umount_client $MOUNT || error "failed to umount client"
10149                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10150                         error "failed to mount client with option '$opt'"
10151                 checksum=$(eval $get_checksum)
10152                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10153                 i=$((i - 1))
10154         done
10155
10156         remount_client $MOUNT || error "failed to remount client"
10157 }
10158 run_test 77k "enable/disable checksum correctly"
10159
10160 test_77l() {
10161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10162         $GSS && skip_env "could not run with gss"
10163
10164         set_checksums 1
10165         stack_trap "set_checksums $ORIG_CSUM" EXIT
10166         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10167
10168         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10169
10170         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10171         for algo in $CKSUM_TYPES; do
10172                 set_checksum_type $algo || error "fail to set checksum type $algo"
10173                 osc_algo=$(get_osc_checksum_type OST0000)
10174                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10175
10176                 # no locks, no reqs to let the connection idle
10177                 cancel_lru_locks osc
10178                 lru_resize_disable osc
10179                 wait_osc_import_state client ost1 IDLE
10180
10181                 # ensure ost1 is connected
10182                 stat $DIR/$tfile >/dev/null || error "can't stat"
10183                 wait_osc_import_state client ost1 FULL
10184
10185                 osc_algo=$(get_osc_checksum_type OST0000)
10186                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10187         done
10188         return 0
10189 }
10190 run_test 77l "preferred checksum type is remembered after reconnected"
10191
10192 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10193 rm -f $F77_TMP
10194 unset F77_TMP
10195
10196 test_77m() {
10197         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10198                 skip "Need at least version 2.14.52"
10199         local param=checksum_speed
10200
10201         $LCTL get_param $param || error "reading $param failed"
10202
10203         csum_speeds=$($LCTL get_param -n $param)
10204
10205         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10206                 error "known checksum types are missing"
10207 }
10208 run_test 77m "Verify checksum_speed is correctly read"
10209
10210 check_filefrag_77n() {
10211         local nr_ext=0
10212         local starts=()
10213         local ends=()
10214
10215         while read extidx a b start end rest; do
10216                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10217                         nr_ext=$(( $nr_ext + 1 ))
10218                         starts+=( ${start%..} )
10219                         ends+=( ${end%:} )
10220                 fi
10221         done < <( filefrag -sv $1 )
10222
10223         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10224         return 1
10225 }
10226
10227 test_77n() {
10228         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10229
10230         touch $DIR/$tfile
10231         $TRUNCATE $DIR/$tfile 0
10232         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10233         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10234         check_filefrag_77n $DIR/$tfile ||
10235                 skip "$tfile blocks not contiguous around hole"
10236
10237         set_checksums 1
10238         stack_trap "set_checksums $ORIG_CSUM" EXIT
10239         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10240         stack_trap "rm -f $DIR/$tfile"
10241
10242         for algo in $CKSUM_TYPES; do
10243                 if [[ "$algo" =~ ^t10 ]]; then
10244                         set_checksum_type $algo ||
10245                                 error "fail to set checksum type $algo"
10246                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10247                                 error "fail to read $tfile with $algo"
10248                 fi
10249         done
10250         rm -f $DIR/$tfile
10251         return 0
10252 }
10253 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10254
10255 test_77o() {
10256         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10257                 skip "Need MDS version at least 2.14.55"
10258         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10259                 skip "Need OST version at least 2.14.55"
10260         local ofd=obdfilter
10261         local mdt=mdt
10262
10263         # print OST checksum_type
10264         echo "$ofd.$FSNAME-*.checksum_type:"
10265         do_nodes $(comma_list $(osts_nodes)) \
10266                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10267
10268         # print MDT checksum_type
10269         echo "$mdt.$FSNAME-*.checksum_type:"
10270         do_nodes $(comma_list $(mdts_nodes)) \
10271                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10272
10273         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10274                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10275
10276         (( $o_count == $OSTCOUNT )) ||
10277                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10278
10279         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10280                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10281
10282         (( $m_count == $MDSCOUNT )) ||
10283                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10284 }
10285 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10286
10287 cleanup_test_78() {
10288         trap 0
10289         rm -f $DIR/$tfile
10290 }
10291
10292 test_78() { # bug 10901
10293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10294         remote_ost || skip_env "local OST"
10295
10296         NSEQ=5
10297         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10298         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10299         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10300         echo "MemTotal: $MEMTOTAL"
10301
10302         # reserve 256MB of memory for the kernel and other running processes,
10303         # and then take 1/2 of the remaining memory for the read/write buffers.
10304         if [ $MEMTOTAL -gt 512 ] ;then
10305                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10306         else
10307                 # for those poor memory-starved high-end clusters...
10308                 MEMTOTAL=$((MEMTOTAL / 2))
10309         fi
10310         echo "Mem to use for directio: $MEMTOTAL"
10311
10312         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10313         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10314         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10315         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10316                 head -n1)
10317         echo "Smallest OST: $SMALLESTOST"
10318         [[ $SMALLESTOST -lt 10240 ]] &&
10319                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10320
10321         trap cleanup_test_78 EXIT
10322
10323         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10324                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10325
10326         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10327         echo "File size: $F78SIZE"
10328         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10329         for i in $(seq 1 $NSEQ); do
10330                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10331                 echo directIO rdwr round $i of $NSEQ
10332                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10333         done
10334
10335         cleanup_test_78
10336 }
10337 run_test 78 "handle large O_DIRECT writes correctly ============"
10338
10339 test_79() { # bug 12743
10340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10341
10342         wait_delete_completed
10343
10344         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10345         BKFREE=$(calc_osc_kbytes kbytesfree)
10346         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10347
10348         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10349         DFTOTAL=`echo $STRING | cut -d, -f1`
10350         DFUSED=`echo $STRING  | cut -d, -f2`
10351         DFAVAIL=`echo $STRING | cut -d, -f3`
10352         DFFREE=$(($DFTOTAL - $DFUSED))
10353
10354         ALLOWANCE=$((64 * $OSTCOUNT))
10355
10356         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10357            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10358                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10359         fi
10360         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10361            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10362                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10363         fi
10364         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10365            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10366                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10367         fi
10368 }
10369 run_test 79 "df report consistency check ======================="
10370
10371 test_80() { # bug 10718
10372         remote_ost_nodsh && skip "remote OST with nodsh"
10373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10374
10375         # relax strong synchronous semantics for slow backends like ZFS
10376         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10377                 local soc="obdfilter.*.sync_lock_cancel"
10378                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10379
10380                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10381                 if [ -z "$save" ]; then
10382                         soc="obdfilter.*.sync_on_lock_cancel"
10383                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10384                 fi
10385
10386                 if [ "$save" != "never" ]; then
10387                         local hosts=$(comma_list $(osts_nodes))
10388
10389                         do_nodes $hosts $LCTL set_param $soc=never
10390                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10391                 fi
10392         fi
10393
10394         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10395         sync; sleep 1; sync
10396         local before=$(date +%s)
10397         cancel_lru_locks osc
10398         local after=$(date +%s)
10399         local diff=$((after - before))
10400         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10401
10402         rm -f $DIR/$tfile
10403 }
10404 run_test 80 "Page eviction is equally fast at high offsets too"
10405
10406 test_81a() { # LU-456
10407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10408         remote_ost_nodsh && skip "remote OST with nodsh"
10409
10410         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10411         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10412         do_facet ost1 lctl set_param fail_loc=0x80000228
10413
10414         # write should trigger a retry and success
10415         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10416         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10417         RC=$?
10418         if [ $RC -ne 0 ] ; then
10419                 error "write should success, but failed for $RC"
10420         fi
10421 }
10422 run_test 81a "OST should retry write when get -ENOSPC ==============="
10423
10424 test_81b() { # LU-456
10425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10426         remote_ost_nodsh && skip "remote OST with nodsh"
10427
10428         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10429         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10430         do_facet ost1 lctl set_param fail_loc=0x228
10431
10432         # write should retry several times and return -ENOSPC finally
10433         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10434         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10435         RC=$?
10436         ENOSPC=28
10437         if [ $RC -ne $ENOSPC ] ; then
10438                 error "dd should fail for -ENOSPC, but succeed."
10439         fi
10440 }
10441 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10442
10443 test_99() {
10444         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10445
10446         test_mkdir $DIR/$tdir.cvsroot
10447         chown $RUNAS_ID $DIR/$tdir.cvsroot
10448
10449         cd $TMP
10450         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10451
10452         cd /etc/init.d
10453         # some versions of cvs import exit(1) when asked to import links or
10454         # files they can't read.  ignore those files.
10455         local toignore=$(find . -type l -printf '-I %f\n' -o \
10456                          ! -perm /4 -printf '-I %f\n')
10457         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10458                 $tdir.reposname vtag rtag
10459
10460         cd $DIR
10461         test_mkdir $DIR/$tdir.reposname
10462         chown $RUNAS_ID $DIR/$tdir.reposname
10463         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10464
10465         cd $DIR/$tdir.reposname
10466         $RUNAS touch foo99
10467         $RUNAS cvs add -m 'addmsg' foo99
10468         $RUNAS cvs update
10469         $RUNAS cvs commit -m 'nomsg' foo99
10470         rm -fr $DIR/$tdir.cvsroot
10471 }
10472 run_test 99 "cvs strange file/directory operations"
10473
10474 test_100() {
10475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10476         [[ "$NETTYPE" =~ tcp ]] ||
10477                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10478         remote_ost_nodsh && skip "remote OST with nodsh"
10479         remote_mds_nodsh && skip "remote MDS with nodsh"
10480         remote_servers ||
10481                 skip "useless for local single node setup"
10482
10483         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10484                 [ "$PROT" != "tcp" ] && continue
10485                 RPORT=$(echo $REMOTE | cut -d: -f2)
10486                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10487
10488                 rc=0
10489                 LPORT=`echo $LOCAL | cut -d: -f2`
10490                 if [ $LPORT -ge 1024 ]; then
10491                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10492                         netstat -tna
10493                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10494                 fi
10495         done
10496         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10497 }
10498 run_test 100 "check local port using privileged port ==========="
10499
10500 function get_named_value()
10501 {
10502     local tag=$1
10503
10504     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10505 }
10506
10507 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10508                    awk '/^max_cached_mb/ { print $2 }')
10509
10510 cleanup_101a() {
10511         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10512         trap 0
10513 }
10514
10515 test_101a() {
10516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10517
10518         local s
10519         local discard
10520         local nreads=10000
10521         local cache_limit=32
10522
10523         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10524         trap cleanup_101a EXIT
10525         $LCTL set_param -n llite.*.read_ahead_stats=0
10526         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10527
10528         #
10529         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10530         #
10531         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10532         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10533
10534         discard=0
10535         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10536                    get_named_value 'read.but.discarded'); do
10537                         discard=$(($discard + $s))
10538         done
10539         cleanup_101a
10540
10541         $LCTL get_param osc.*-osc*.rpc_stats
10542         $LCTL get_param llite.*.read_ahead_stats
10543
10544         # Discard is generally zero, but sometimes a few random reads line up
10545         # and trigger larger readahead, which is wasted & leads to discards.
10546         if [[ $(($discard)) -gt $nreads ]]; then
10547                 error "too many ($discard) discarded pages"
10548         fi
10549         rm -f $DIR/$tfile || true
10550 }
10551 run_test 101a "check read-ahead for random reads"
10552
10553 setup_test101bc() {
10554         test_mkdir $DIR/$tdir
10555         local ssize=$1
10556         local FILE_LENGTH=$2
10557         STRIPE_OFFSET=0
10558
10559         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10560
10561         local list=$(comma_list $(osts_nodes))
10562         set_osd_param $list '' read_cache_enable 0
10563         set_osd_param $list '' writethrough_cache_enable 0
10564
10565         trap cleanup_test101bc EXIT
10566         # prepare the read-ahead file
10567         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10568
10569         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10570                                 count=$FILE_SIZE_MB 2> /dev/null
10571
10572 }
10573
10574 cleanup_test101bc() {
10575         trap 0
10576         rm -rf $DIR/$tdir
10577         rm -f $DIR/$tfile
10578
10579         local list=$(comma_list $(osts_nodes))
10580         set_osd_param $list '' read_cache_enable 1
10581         set_osd_param $list '' writethrough_cache_enable 1
10582 }
10583
10584 calc_total() {
10585         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10586 }
10587
10588 ra_check_101() {
10589         local read_size=$1
10590         local stripe_size=$2
10591         local stride_length=$((stripe_size / read_size))
10592         local stride_width=$((stride_length * OSTCOUNT))
10593         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10594                                 (stride_width - stride_length) ))
10595         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10596                   get_named_value 'read.but.discarded' | calc_total)
10597
10598         if [[ $discard -gt $discard_limit ]]; then
10599                 $LCTL get_param llite.*.read_ahead_stats
10600                 error "($discard) discarded pages with size (${read_size})"
10601         else
10602                 echo "Read-ahead success for size ${read_size}"
10603         fi
10604 }
10605
10606 test_101b() {
10607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10608         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10609
10610         local STRIPE_SIZE=1048576
10611         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10612
10613         if [ $SLOW == "yes" ]; then
10614                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10615         else
10616                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10617         fi
10618
10619         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10620
10621         # prepare the read-ahead file
10622         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10623         cancel_lru_locks osc
10624         for BIDX in 2 4 8 16 32 64 128 256
10625         do
10626                 local BSIZE=$((BIDX*4096))
10627                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10628                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10629                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10630                 $LCTL set_param -n llite.*.read_ahead_stats=0
10631                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10632                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10633                 cancel_lru_locks osc
10634                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10635         done
10636         cleanup_test101bc
10637         true
10638 }
10639 run_test 101b "check stride-io mode read-ahead ================="
10640
10641 test_101c() {
10642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10643
10644         local STRIPE_SIZE=1048576
10645         local FILE_LENGTH=$((STRIPE_SIZE*100))
10646         local nreads=10000
10647         local rsize=65536
10648         local osc_rpc_stats
10649
10650         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10651
10652         cancel_lru_locks osc
10653         $LCTL set_param osc.*.rpc_stats=0
10654         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10655         $LCTL get_param osc.*.rpc_stats
10656         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10657                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10658                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10659                 local size
10660
10661                 if [ $lines -le 20 ]; then
10662                         echo "continue debug"
10663                         continue
10664                 fi
10665                 for size in 1 2 4 8; do
10666                         local rpc=$(echo "$stats" |
10667                                     awk '($1 == "'$size':") {print $2; exit; }')
10668                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10669                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10670                 done
10671                 echo "$osc_rpc_stats check passed!"
10672         done
10673         cleanup_test101bc
10674         true
10675 }
10676 run_test 101c "check stripe_size aligned read-ahead"
10677
10678 test_101d() {
10679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10680
10681         local file=$DIR/$tfile
10682         local sz_MB=${FILESIZE_101d:-80}
10683         local ra_MB=${READAHEAD_MB:-40}
10684
10685         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10686         [ $free_MB -lt $sz_MB ] &&
10687                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10688
10689         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10690         $LFS setstripe -c -1 $file || error "setstripe failed"
10691
10692         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10693         echo Cancel LRU locks on lustre client to flush the client cache
10694         cancel_lru_locks osc
10695
10696         echo Disable read-ahead
10697         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10698         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10699         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10700         $LCTL get_param -n llite.*.max_read_ahead_mb
10701
10702         echo "Reading the test file $file with read-ahead disabled"
10703         local sz_KB=$((sz_MB * 1024 / 4))
10704         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10705         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10706         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10707                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10708
10709         echo "Cancel LRU locks on lustre client to flush the client cache"
10710         cancel_lru_locks osc
10711         echo Enable read-ahead with ${ra_MB}MB
10712         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10713
10714         echo "Reading the test file $file with read-ahead enabled"
10715         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10716                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10717
10718         echo "read-ahead disabled time read $raOFF"
10719         echo "read-ahead enabled time read $raON"
10720
10721         rm -f $file
10722         wait_delete_completed
10723
10724         # use awk for this check instead of bash because it handles decimals
10725         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10726                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10727 }
10728 run_test 101d "file read with and without read-ahead enabled"
10729
10730 test_101e() {
10731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10732
10733         local file=$DIR/$tfile
10734         local size_KB=500  #KB
10735         local count=100
10736         local bsize=1024
10737
10738         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10739         local need_KB=$((count * size_KB))
10740         [[ $free_KB -le $need_KB ]] &&
10741                 skip_env "Need free space $need_KB, have $free_KB"
10742
10743         echo "Creating $count ${size_KB}K test files"
10744         for ((i = 0; i < $count; i++)); do
10745                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10746         done
10747
10748         echo "Cancel LRU locks on lustre client to flush the client cache"
10749         cancel_lru_locks $OSC
10750
10751         echo "Reset readahead stats"
10752         $LCTL set_param -n llite.*.read_ahead_stats=0
10753
10754         for ((i = 0; i < $count; i++)); do
10755                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10756         done
10757
10758         $LCTL get_param llite.*.max_cached_mb
10759         $LCTL get_param llite.*.read_ahead_stats
10760         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10761                      get_named_value 'misses' | calc_total)
10762
10763         for ((i = 0; i < $count; i++)); do
10764                 rm -rf $file.$i 2>/dev/null
10765         done
10766
10767         #10000 means 20% reads are missing in readahead
10768         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10769 }
10770 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10771
10772 test_101f() {
10773         which iozone || skip_env "no iozone installed"
10774
10775         local old_debug=$($LCTL get_param debug)
10776         old_debug=${old_debug#*=}
10777         $LCTL set_param debug="reada mmap"
10778
10779         # create a test file
10780         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10781
10782         echo Cancel LRU locks on lustre client to flush the client cache
10783         cancel_lru_locks osc
10784
10785         echo Reset readahead stats
10786         $LCTL set_param -n llite.*.read_ahead_stats=0
10787
10788         echo mmap read the file with small block size
10789         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10790                 > /dev/null 2>&1
10791
10792         echo checking missing pages
10793         $LCTL get_param llite.*.read_ahead_stats
10794         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10795                         get_named_value 'misses' | calc_total)
10796
10797         $LCTL set_param debug="$old_debug"
10798         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10799         rm -f $DIR/$tfile
10800 }
10801 run_test 101f "check mmap read performance"
10802
10803 test_101g_brw_size_test() {
10804         local mb=$1
10805         local pages=$((mb * 1048576 / PAGE_SIZE))
10806         local file=$DIR/$tfile
10807
10808         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10809                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10810         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10811                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10812                         return 2
10813         done
10814
10815         stack_trap "rm -f $file" EXIT
10816         $LCTL set_param -n osc.*.rpc_stats=0
10817
10818         # 10 RPCs should be enough for the test
10819         local count=10
10820         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10821                 { error "dd write ${mb} MB blocks failed"; return 3; }
10822         cancel_lru_locks osc
10823         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10824                 { error "dd write ${mb} MB blocks failed"; return 4; }
10825
10826         # calculate number of full-sized read and write RPCs
10827         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10828                 sed -n '/pages per rpc/,/^$/p' |
10829                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10830                 END { print reads,writes }'))
10831         # allow one extra full-sized read RPC for async readahead
10832         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10833                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10834         [[ ${rpcs[1]} == $count ]] ||
10835                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10836 }
10837
10838 test_101g() {
10839         remote_ost_nodsh && skip "remote OST with nodsh"
10840
10841         local rpcs
10842         local osts=$(get_facets OST)
10843         local list=$(comma_list $(osts_nodes))
10844         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10845         local brw_size="obdfilter.*.brw_size"
10846
10847         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10848
10849         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10850
10851         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10852                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10853                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10854            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10855                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10856                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10857
10858                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10859                         suffix="M"
10860
10861                 if [[ $orig_mb -lt 16 ]]; then
10862                         save_lustre_params $osts "$brw_size" > $p
10863                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10864                                 error "set 16MB RPC size failed"
10865
10866                         echo "remount client to enable new RPC size"
10867                         remount_client $MOUNT || error "remount_client failed"
10868                 fi
10869
10870                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10871                 # should be able to set brw_size=12, but no rpc_stats for that
10872                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10873         fi
10874
10875         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10876
10877         if [[ $orig_mb -lt 16 ]]; then
10878                 restore_lustre_params < $p
10879                 remount_client $MOUNT || error "remount_client restore failed"
10880         fi
10881
10882         rm -f $p $DIR/$tfile
10883 }
10884 run_test 101g "Big bulk(4/16 MiB) readahead"
10885
10886 test_101h() {
10887         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10888
10889         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10890                 error "dd 70M file failed"
10891         echo Cancel LRU locks on lustre client to flush the client cache
10892         cancel_lru_locks osc
10893
10894         echo "Reset readahead stats"
10895         $LCTL set_param -n llite.*.read_ahead_stats 0
10896
10897         echo "Read 10M of data but cross 64M bundary"
10898         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10899         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10900                      get_named_value 'misses' | calc_total)
10901         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10902         rm -f $p $DIR/$tfile
10903 }
10904 run_test 101h "Readahead should cover current read window"
10905
10906 test_101i() {
10907         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10908                 error "dd 10M file failed"
10909
10910         local max_per_file_mb=$($LCTL get_param -n \
10911                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10912         cancel_lru_locks osc
10913         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10914         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10915                 error "set max_read_ahead_per_file_mb to 1 failed"
10916
10917         echo "Reset readahead stats"
10918         $LCTL set_param llite.*.read_ahead_stats=0
10919
10920         dd if=$DIR/$tfile of=/dev/null bs=2M
10921
10922         $LCTL get_param llite.*.read_ahead_stats
10923         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10924                      awk '/misses/ { print $2 }')
10925         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10926         rm -f $DIR/$tfile
10927 }
10928 run_test 101i "allow current readahead to exceed reservation"
10929
10930 test_101j() {
10931         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10932                 error "setstripe $DIR/$tfile failed"
10933         local file_size=$((1048576 * 16))
10934         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10935         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10936
10937         echo Disable read-ahead
10938         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10939
10940         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10941         for blk in $PAGE_SIZE 1048576 $file_size; do
10942                 cancel_lru_locks osc
10943                 echo "Reset readahead stats"
10944                 $LCTL set_param -n llite.*.read_ahead_stats=0
10945                 local count=$(($file_size / $blk))
10946                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10947                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10948                              get_named_value 'failed.to.fast.read' | calc_total)
10949                 $LCTL get_param -n llite.*.read_ahead_stats
10950                 [ $miss -eq $count ] || error "expected $count got $miss"
10951         done
10952
10953         rm -f $p $DIR/$tfile
10954 }
10955 run_test 101j "A complete read block should be submitted when no RA"
10956
10957 setup_test102() {
10958         test_mkdir $DIR/$tdir
10959         chown $RUNAS_ID $DIR/$tdir
10960         STRIPE_SIZE=65536
10961         STRIPE_OFFSET=1
10962         STRIPE_COUNT=$OSTCOUNT
10963         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10964
10965         trap cleanup_test102 EXIT
10966         cd $DIR
10967         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10968         cd $DIR/$tdir
10969         for num in 1 2 3 4; do
10970                 for count in $(seq 1 $STRIPE_COUNT); do
10971                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10972                                 local size=`expr $STRIPE_SIZE \* $num`
10973                                 local file=file"$num-$idx-$count"
10974                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10975                         done
10976                 done
10977         done
10978
10979         cd $DIR
10980         $1 tar cf $TMP/f102.tar $tdir --xattrs
10981 }
10982
10983 cleanup_test102() {
10984         trap 0
10985         rm -f $TMP/f102.tar
10986         rm -rf $DIR/d0.sanity/d102
10987 }
10988
10989 test_102a() {
10990         [ "$UID" != 0 ] && skip "must run as root"
10991         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10992                 skip_env "must have user_xattr"
10993
10994         [ -z "$(which setfattr 2>/dev/null)" ] &&
10995                 skip_env "could not find setfattr"
10996
10997         local testfile=$DIR/$tfile
10998
10999         touch $testfile
11000         echo "set/get xattr..."
11001         setfattr -n trusted.name1 -v value1 $testfile ||
11002                 error "setfattr -n trusted.name1=value1 $testfile failed"
11003         getfattr -n trusted.name1 $testfile 2> /dev/null |
11004           grep "trusted.name1=.value1" ||
11005                 error "$testfile missing trusted.name1=value1"
11006
11007         setfattr -n user.author1 -v author1 $testfile ||
11008                 error "setfattr -n user.author1=author1 $testfile failed"
11009         getfattr -n user.author1 $testfile 2> /dev/null |
11010           grep "user.author1=.author1" ||
11011                 error "$testfile missing trusted.author1=author1"
11012
11013         echo "listxattr..."
11014         setfattr -n trusted.name2 -v value2 $testfile ||
11015                 error "$testfile unable to set trusted.name2"
11016         setfattr -n trusted.name3 -v value3 $testfile ||
11017                 error "$testfile unable to set trusted.name3"
11018         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11019             grep "trusted.name" | wc -l) -eq 3 ] ||
11020                 error "$testfile missing 3 trusted.name xattrs"
11021
11022         setfattr -n user.author2 -v author2 $testfile ||
11023                 error "$testfile unable to set user.author2"
11024         setfattr -n user.author3 -v author3 $testfile ||
11025                 error "$testfile unable to set user.author3"
11026         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11027             grep "user.author" | wc -l) -eq 3 ] ||
11028                 error "$testfile missing 3 user.author xattrs"
11029
11030         echo "remove xattr..."
11031         setfattr -x trusted.name1 $testfile ||
11032                 error "$testfile error deleting trusted.name1"
11033         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11034                 error "$testfile did not delete trusted.name1 xattr"
11035
11036         setfattr -x user.author1 $testfile ||
11037                 error "$testfile error deleting user.author1"
11038         echo "set lustre special xattr ..."
11039         $LFS setstripe -c1 $testfile
11040         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11041                 awk -F "=" '/trusted.lov/ { print $2 }' )
11042         setfattr -n "trusted.lov" -v $lovea $testfile ||
11043                 error "$testfile doesn't ignore setting trusted.lov again"
11044         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11045                 error "$testfile allow setting invalid trusted.lov"
11046         rm -f $testfile
11047 }
11048 run_test 102a "user xattr test =================================="
11049
11050 check_102b_layout() {
11051         local layout="$*"
11052         local testfile=$DIR/$tfile
11053
11054         echo "test layout '$layout'"
11055         $LFS setstripe $layout $testfile || error "setstripe failed"
11056         $LFS getstripe -y $testfile
11057
11058         echo "get/set/list trusted.lov xattr ..." # b=10930
11059         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11060         [[ "$value" =~ "trusted.lov" ]] ||
11061                 error "can't get trusted.lov from $testfile"
11062         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11063                 error "getstripe failed"
11064
11065         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11066
11067         value=$(cut -d= -f2 <<<$value)
11068         # LU-13168: truncated xattr should fail if short lov_user_md header
11069         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11070                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11071         for len in $lens; do
11072                 echo "setfattr $len $testfile.2"
11073                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11074                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11075         done
11076         local stripe_size=$($LFS getstripe -S $testfile.2)
11077         local stripe_count=$($LFS getstripe -c $testfile.2)
11078         [[ $stripe_size -eq 65536 ]] ||
11079                 error "stripe size $stripe_size != 65536"
11080         [[ $stripe_count -eq $stripe_count_orig ]] ||
11081                 error "stripe count $stripe_count != $stripe_count_orig"
11082         rm $testfile $testfile.2
11083 }
11084
11085 test_102b() {
11086         [ -z "$(which setfattr 2>/dev/null)" ] &&
11087                 skip_env "could not find setfattr"
11088         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11089
11090         # check plain layout
11091         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11092
11093         # and also check composite layout
11094         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11095
11096 }
11097 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11098
11099 test_102c() {
11100         [ -z "$(which setfattr 2>/dev/null)" ] &&
11101                 skip_env "could not find setfattr"
11102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11103
11104         # b10930: get/set/list lustre.lov xattr
11105         echo "get/set/list lustre.lov xattr ..."
11106         test_mkdir $DIR/$tdir
11107         chown $RUNAS_ID $DIR/$tdir
11108         local testfile=$DIR/$tdir/$tfile
11109         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11110                 error "setstripe failed"
11111         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11112                 error "getstripe failed"
11113         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11114         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11115
11116         local testfile2=${testfile}2
11117         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11118                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11119
11120         $RUNAS $MCREATE $testfile2
11121         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11122         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11123         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11124         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11125         [ $stripe_count -eq $STRIPECOUNT ] ||
11126                 error "stripe count $stripe_count != $STRIPECOUNT"
11127 }
11128 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11129
11130 compare_stripe_info1() {
11131         local stripe_index_all_zero=true
11132
11133         for num in 1 2 3 4; do
11134                 for count in $(seq 1 $STRIPE_COUNT); do
11135                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11136                                 local size=$((STRIPE_SIZE * num))
11137                                 local file=file"$num-$offset-$count"
11138                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11139                                 [[ $stripe_size -ne $size ]] &&
11140                                     error "$file: size $stripe_size != $size"
11141                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11142                                 # allow fewer stripes to be created, ORI-601
11143                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11144                                     error "$file: count $stripe_count != $count"
11145                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11146                                 [[ $stripe_index -ne 0 ]] &&
11147                                         stripe_index_all_zero=false
11148                         done
11149                 done
11150         done
11151         $stripe_index_all_zero &&
11152                 error "all files are being extracted starting from OST index 0"
11153         return 0
11154 }
11155
11156 have_xattrs_include() {
11157         tar --help | grep -q xattrs-include &&
11158                 echo --xattrs-include="lustre.*"
11159 }
11160
11161 test_102d() {
11162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11163         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11164
11165         XINC=$(have_xattrs_include)
11166         setup_test102
11167         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11168         cd $DIR/$tdir/$tdir
11169         compare_stripe_info1
11170 }
11171 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11172
11173 test_102f() {
11174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11175         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11176
11177         XINC=$(have_xattrs_include)
11178         setup_test102
11179         test_mkdir $DIR/$tdir.restore
11180         cd $DIR
11181         tar cf - --xattrs $tdir | tar xf - \
11182                 -C $DIR/$tdir.restore --xattrs $XINC
11183         cd $DIR/$tdir.restore/$tdir
11184         compare_stripe_info1
11185 }
11186 run_test 102f "tar copy files, not keep osts"
11187
11188 grow_xattr() {
11189         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11190                 skip "must have user_xattr"
11191         [ -z "$(which setfattr 2>/dev/null)" ] &&
11192                 skip_env "could not find setfattr"
11193         [ -z "$(which getfattr 2>/dev/null)" ] &&
11194                 skip_env "could not find getfattr"
11195
11196         local xsize=${1:-1024}  # in bytes
11197         local file=$DIR/$tfile
11198         local value="$(generate_string $xsize)"
11199         local xbig=trusted.big
11200         local toobig=$2
11201
11202         touch $file
11203         log "save $xbig on $file"
11204         if [ -z "$toobig" ]
11205         then
11206                 setfattr -n $xbig -v $value $file ||
11207                         error "saving $xbig on $file failed"
11208         else
11209                 setfattr -n $xbig -v $value $file &&
11210                         error "saving $xbig on $file succeeded"
11211                 return 0
11212         fi
11213
11214         local orig=$(get_xattr_value $xbig $file)
11215         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11216
11217         local xsml=trusted.sml
11218         log "save $xsml on $file"
11219         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11220
11221         local new=$(get_xattr_value $xbig $file)
11222         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11223
11224         log "grow $xsml on $file"
11225         setfattr -n $xsml -v "$value" $file ||
11226                 error "growing $xsml on $file failed"
11227
11228         new=$(get_xattr_value $xbig $file)
11229         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11230         log "$xbig still valid after growing $xsml"
11231
11232         rm -f $file
11233 }
11234
11235 test_102h() { # bug 15777
11236         grow_xattr 1024
11237 }
11238 run_test 102h "grow xattr from inside inode to external block"
11239
11240 test_102ha() {
11241         large_xattr_enabled || skip_env "ea_inode feature disabled"
11242
11243         echo "setting xattr of max xattr size: $(max_xattr_size)"
11244         grow_xattr $(max_xattr_size)
11245
11246         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11247         echo "This should fail:"
11248         grow_xattr $(($(max_xattr_size) + 10)) 1
11249 }
11250 run_test 102ha "grow xattr from inside inode to external inode"
11251
11252 test_102i() { # bug 17038
11253         [ -z "$(which getfattr 2>/dev/null)" ] &&
11254                 skip "could not find getfattr"
11255
11256         touch $DIR/$tfile
11257         ln -s $DIR/$tfile $DIR/${tfile}link
11258         getfattr -n trusted.lov $DIR/$tfile ||
11259                 error "lgetxattr on $DIR/$tfile failed"
11260         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11261                 grep -i "no such attr" ||
11262                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11263         rm -f $DIR/$tfile $DIR/${tfile}link
11264 }
11265 run_test 102i "lgetxattr test on symbolic link ============"
11266
11267 test_102j() {
11268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11269         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11270
11271         XINC=$(have_xattrs_include)
11272         setup_test102 "$RUNAS"
11273         chown $RUNAS_ID $DIR/$tdir
11274         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11275         cd $DIR/$tdir/$tdir
11276         compare_stripe_info1 "$RUNAS"
11277 }
11278 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11279
11280 test_102k() {
11281         [ -z "$(which setfattr 2>/dev/null)" ] &&
11282                 skip "could not find setfattr"
11283
11284         touch $DIR/$tfile
11285         # b22187 just check that does not crash for regular file.
11286         setfattr -n trusted.lov $DIR/$tfile
11287         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11288         local test_kdir=$DIR/$tdir
11289         test_mkdir $test_kdir
11290         local default_size=$($LFS getstripe -S $test_kdir)
11291         local default_count=$($LFS getstripe -c $test_kdir)
11292         local default_offset=$($LFS getstripe -i $test_kdir)
11293         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11294                 error 'dir setstripe failed'
11295         setfattr -n trusted.lov $test_kdir
11296         local stripe_size=$($LFS getstripe -S $test_kdir)
11297         local stripe_count=$($LFS getstripe -c $test_kdir)
11298         local stripe_offset=$($LFS getstripe -i $test_kdir)
11299         [ $stripe_size -eq $default_size ] ||
11300                 error "stripe size $stripe_size != $default_size"
11301         [ $stripe_count -eq $default_count ] ||
11302                 error "stripe count $stripe_count != $default_count"
11303         [ $stripe_offset -eq $default_offset ] ||
11304                 error "stripe offset $stripe_offset != $default_offset"
11305         rm -rf $DIR/$tfile $test_kdir
11306 }
11307 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11308
11309 test_102l() {
11310         [ -z "$(which getfattr 2>/dev/null)" ] &&
11311                 skip "could not find getfattr"
11312
11313         # LU-532 trusted. xattr is invisible to non-root
11314         local testfile=$DIR/$tfile
11315
11316         touch $testfile
11317
11318         echo "listxattr as user..."
11319         chown $RUNAS_ID $testfile
11320         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11321             grep -q "trusted" &&
11322                 error "$testfile trusted xattrs are user visible"
11323
11324         return 0;
11325 }
11326 run_test 102l "listxattr size test =================================="
11327
11328 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11329         local path=$DIR/$tfile
11330         touch $path
11331
11332         listxattr_size_check $path || error "listattr_size_check $path failed"
11333 }
11334 run_test 102m "Ensure listxattr fails on small bufffer ========"
11335
11336 cleanup_test102
11337
11338 getxattr() { # getxattr path name
11339         # Return the base64 encoding of the value of xattr name on path.
11340         local path=$1
11341         local name=$2
11342
11343         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11344         # file: $path
11345         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11346         #
11347         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11348
11349         getfattr --absolute-names --encoding=base64 --name=$name $path |
11350                 awk -F= -v name=$name '$1 == name {
11351                         print substr($0, index($0, "=") + 1);
11352         }'
11353 }
11354
11355 test_102n() { # LU-4101 mdt: protect internal xattrs
11356         [ -z "$(which setfattr 2>/dev/null)" ] &&
11357                 skip "could not find setfattr"
11358         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11359         then
11360                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11361         fi
11362
11363         local file0=$DIR/$tfile.0
11364         local file1=$DIR/$tfile.1
11365         local xattr0=$TMP/$tfile.0
11366         local xattr1=$TMP/$tfile.1
11367         local namelist="lov lma lmv link fid version som hsm"
11368         local name
11369         local value
11370
11371         rm -rf $file0 $file1 $xattr0 $xattr1
11372         touch $file0 $file1
11373
11374         # Get 'before' xattrs of $file1.
11375         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11376
11377         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11378                 namelist+=" lfsck_namespace"
11379         for name in $namelist; do
11380                 # Try to copy xattr from $file0 to $file1.
11381                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11382
11383                 setfattr --name=trusted.$name --value="$value" $file1 ||
11384                         error "setxattr 'trusted.$name' failed"
11385
11386                 # Try to set a garbage xattr.
11387                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11388
11389                 if [[ x$name == "xlov" ]]; then
11390                         setfattr --name=trusted.lov --value="$value" $file1 &&
11391                         error "setxattr invalid 'trusted.lov' success"
11392                 else
11393                         setfattr --name=trusted.$name --value="$value" $file1 ||
11394                                 error "setxattr invalid 'trusted.$name' failed"
11395                 fi
11396
11397                 # Try to remove the xattr from $file1. We don't care if this
11398                 # appears to succeed or fail, we just don't want there to be
11399                 # any changes or crashes.
11400                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11401         done
11402
11403         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11404         then
11405                 name="lfsck_ns"
11406                 # Try to copy xattr from $file0 to $file1.
11407                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11408
11409                 setfattr --name=trusted.$name --value="$value" $file1 ||
11410                         error "setxattr 'trusted.$name' failed"
11411
11412                 # Try to set a garbage xattr.
11413                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11414
11415                 setfattr --name=trusted.$name --value="$value" $file1 ||
11416                         error "setxattr 'trusted.$name' failed"
11417
11418                 # Try to remove the xattr from $file1. We don't care if this
11419                 # appears to succeed or fail, we just don't want there to be
11420                 # any changes or crashes.
11421                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11422         fi
11423
11424         # Get 'after' xattrs of file1.
11425         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11426
11427         if ! diff $xattr0 $xattr1; then
11428                 error "before and after xattrs of '$file1' differ"
11429         fi
11430
11431         rm -rf $file0 $file1 $xattr0 $xattr1
11432
11433         return 0
11434 }
11435 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11436
11437 test_102p() { # LU-4703 setxattr did not check ownership
11438         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11439                 skip "MDS needs to be at least 2.5.56"
11440
11441         local testfile=$DIR/$tfile
11442
11443         touch $testfile
11444
11445         echo "setfacl as user..."
11446         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11447         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11448
11449         echo "setfattr as user..."
11450         setfacl -m "u:$RUNAS_ID:---" $testfile
11451         $RUNAS setfattr -x system.posix_acl_access $testfile
11452         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11453 }
11454 run_test 102p "check setxattr(2) correctly fails without permission"
11455
11456 test_102q() {
11457         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11458                 skip "MDS needs to be at least 2.6.92"
11459
11460         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11461 }
11462 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11463
11464 test_102r() {
11465         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11466                 skip "MDS needs to be at least 2.6.93"
11467
11468         touch $DIR/$tfile || error "touch"
11469         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11470         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11471         rm $DIR/$tfile || error "rm"
11472
11473         #normal directory
11474         mkdir -p $DIR/$tdir || error "mkdir"
11475         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11476         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11477         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11478                 error "$testfile error deleting user.author1"
11479         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11480                 grep "user.$(basename $tdir)" &&
11481                 error "$tdir did not delete user.$(basename $tdir)"
11482         rmdir $DIR/$tdir || error "rmdir"
11483
11484         #striped directory
11485         test_mkdir $DIR/$tdir
11486         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11487         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11488         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11489                 error "$testfile error deleting user.author1"
11490         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11491                 grep "user.$(basename $tdir)" &&
11492                 error "$tdir did not delete user.$(basename $tdir)"
11493         rmdir $DIR/$tdir || error "rm striped dir"
11494 }
11495 run_test 102r "set EAs with empty values"
11496
11497 test_102s() {
11498         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11499                 skip "MDS needs to be at least 2.11.52"
11500
11501         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11502
11503         save_lustre_params client "llite.*.xattr_cache" > $save
11504
11505         for cache in 0 1; do
11506                 lctl set_param llite.*.xattr_cache=$cache
11507
11508                 rm -f $DIR/$tfile
11509                 touch $DIR/$tfile || error "touch"
11510                 for prefix in lustre security system trusted user; do
11511                         # Note getxattr() may fail with 'Operation not
11512                         # supported' or 'No such attribute' depending
11513                         # on prefix and cache.
11514                         getfattr -n $prefix.n102s $DIR/$tfile &&
11515                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11516                 done
11517         done
11518
11519         restore_lustre_params < $save
11520 }
11521 run_test 102s "getting nonexistent xattrs should fail"
11522
11523 test_102t() {
11524         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11525                 skip "MDS needs to be at least 2.11.52"
11526
11527         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11528
11529         save_lustre_params client "llite.*.xattr_cache" > $save
11530
11531         for cache in 0 1; do
11532                 lctl set_param llite.*.xattr_cache=$cache
11533
11534                 for buf_size in 0 256; do
11535                         rm -f $DIR/$tfile
11536                         touch $DIR/$tfile || error "touch"
11537                         setfattr -n user.multiop $DIR/$tfile
11538                         $MULTIOP $DIR/$tfile oa$buf_size ||
11539                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11540                 done
11541         done
11542
11543         restore_lustre_params < $save
11544 }
11545 run_test 102t "zero length xattr values handled correctly"
11546
11547 run_acl_subtest()
11548 {
11549     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11550     return $?
11551 }
11552
11553 test_103a() {
11554         [ "$UID" != 0 ] && skip "must run as root"
11555         $GSS && skip_env "could not run under gss"
11556         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11557                 skip_env "must have acl enabled"
11558         [ -z "$(which setfacl 2>/dev/null)" ] &&
11559                 skip_env "could not find setfacl"
11560         remote_mds_nodsh && skip "remote MDS with nodsh"
11561
11562         gpasswd -a daemon bin                           # LU-5641
11563         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11564
11565         declare -a identity_old
11566
11567         for num in $(seq $MDSCOUNT); do
11568                 switch_identity $num true || identity_old[$num]=$?
11569         done
11570
11571         SAVE_UMASK=$(umask)
11572         umask 0022
11573         mkdir -p $DIR/$tdir
11574         cd $DIR/$tdir
11575
11576         echo "performing cp ..."
11577         run_acl_subtest cp || error "run_acl_subtest cp failed"
11578         echo "performing getfacl-noacl..."
11579         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11580         echo "performing misc..."
11581         run_acl_subtest misc || error  "misc test failed"
11582         echo "performing permissions..."
11583         run_acl_subtest permissions || error "permissions failed"
11584         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11585         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11586                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11587                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11588         then
11589                 echo "performing permissions xattr..."
11590                 run_acl_subtest permissions_xattr ||
11591                         error "permissions_xattr failed"
11592         fi
11593         echo "performing setfacl..."
11594         run_acl_subtest setfacl || error  "setfacl test failed"
11595
11596         # inheritance test got from HP
11597         echo "performing inheritance..."
11598         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11599         chmod +x make-tree || error "chmod +x failed"
11600         run_acl_subtest inheritance || error "inheritance test failed"
11601         rm -f make-tree
11602
11603         echo "LU-974 ignore umask when acl is enabled..."
11604         run_acl_subtest 974 || error "LU-974 umask test failed"
11605         if [ $MDSCOUNT -ge 2 ]; then
11606                 run_acl_subtest 974_remote ||
11607                         error "LU-974 umask test failed under remote dir"
11608         fi
11609
11610         echo "LU-2561 newly created file is same size as directory..."
11611         if [ "$mds1_FSTYPE" != "zfs" ]; then
11612                 run_acl_subtest 2561 || error "LU-2561 test failed"
11613         else
11614                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11615         fi
11616
11617         run_acl_subtest 4924 || error "LU-4924 test failed"
11618
11619         cd $SAVE_PWD
11620         umask $SAVE_UMASK
11621
11622         for num in $(seq $MDSCOUNT); do
11623                 if [ "${identity_old[$num]}" = 1 ]; then
11624                         switch_identity $num false || identity_old[$num]=$?
11625                 fi
11626         done
11627 }
11628 run_test 103a "acl test"
11629
11630 test_103b() {
11631         declare -a pids
11632         local U
11633
11634         for U in {0..511}; do
11635                 {
11636                 local O=$(printf "%04o" $U)
11637
11638                 umask $(printf "%04o" $((511 ^ $O)))
11639                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11640                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11641
11642                 (( $S == ($O & 0666) )) ||
11643                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11644
11645                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11646                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11647                 (( $S == ($O & 0666) )) ||
11648                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11649
11650                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11651                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11652                 (( $S == ($O & 0666) )) ||
11653                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11654                 rm -f $DIR/$tfile.[smp]$0
11655                 } &
11656                 local pid=$!
11657
11658                 # limit the concurrently running threads to 64. LU-11878
11659                 local idx=$((U % 64))
11660                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11661                 pids[idx]=$pid
11662         done
11663         wait
11664 }
11665 run_test 103b "umask lfs setstripe"
11666
11667 test_103c() {
11668         mkdir -p $DIR/$tdir
11669         cp -rp $DIR/$tdir $DIR/$tdir.bak
11670
11671         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11672                 error "$DIR/$tdir shouldn't contain default ACL"
11673         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11674                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11675         true
11676 }
11677 run_test 103c "'cp -rp' won't set empty acl"
11678
11679 test_103e() {
11680         local numacl
11681         local fileacl
11682         local saved_debug=$($LCTL get_param -n debug)
11683
11684         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11685                 skip "MDS needs to be at least 2.14.52"
11686
11687         large_xattr_enabled || skip_env "ea_inode feature disabled"
11688
11689         mkdir -p $DIR/$tdir
11690         # add big LOV EA to cause reply buffer overflow earlier
11691         $LFS setstripe -C 1000 $DIR/$tdir
11692         lctl set_param mdc.*-mdc*.stats=clear
11693
11694         $LCTL set_param debug=0
11695         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11696         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11697
11698         # add a large number of default ACLs (expect 8000+ for 2.13+)
11699         for U in {2..7000}; do
11700                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11701                         error "Able to add just $U default ACLs"
11702         done
11703         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11704         echo "$numacl default ACLs created"
11705
11706         stat $DIR/$tdir || error "Cannot stat directory"
11707         # check file creation
11708         touch $DIR/$tdir/$tfile ||
11709                 error "failed to create $tfile with $numacl default ACLs"
11710         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11711         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11712         echo "$fileacl ACLs were inherited"
11713         (( $fileacl == $numacl )) ||
11714                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11715         # check that new ACLs creation adds new ACLs to inherited ACLs
11716         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11717                 error "Cannot set new ACL"
11718         numacl=$((numacl + 1))
11719         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11720         (( $fileacl == $numacl )) ||
11721                 error "failed to add new ACL: $fileacl != $numacl as expected"
11722         # adds more ACLs to a file to reach their maximum at 8000+
11723         numacl=0
11724         for U in {20000..25000}; do
11725                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11726                 numacl=$((numacl + 1))
11727         done
11728         echo "Added $numacl more ACLs to the file"
11729         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11730         echo "Total $fileacl ACLs in file"
11731         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11732         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11733         rmdir $DIR/$tdir || error "Cannot remove directory"
11734 }
11735 run_test 103e "inheritance of big amount of default ACLs"
11736
11737 test_103f() {
11738         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11739                 skip "MDS needs to be at least 2.14.51"
11740
11741         large_xattr_enabled || skip_env "ea_inode feature disabled"
11742
11743         # enable changelog to consume more internal MDD buffers
11744         changelog_register
11745
11746         mkdir -p $DIR/$tdir
11747         # add big LOV EA
11748         $LFS setstripe -C 1000 $DIR/$tdir
11749         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11750         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11751         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11752         rmdir $DIR/$tdir || error "Cannot remove directory"
11753 }
11754 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11755
11756 test_104a() {
11757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11758
11759         touch $DIR/$tfile
11760         lfs df || error "lfs df failed"
11761         lfs df -ih || error "lfs df -ih failed"
11762         lfs df -h $DIR || error "lfs df -h $DIR failed"
11763         lfs df -i $DIR || error "lfs df -i $DIR failed"
11764         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11765         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11766
11767         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11768         lctl --device %$OSC deactivate
11769         lfs df || error "lfs df with deactivated OSC failed"
11770         lctl --device %$OSC activate
11771         # wait the osc back to normal
11772         wait_osc_import_ready client ost
11773
11774         lfs df || error "lfs df with reactivated OSC failed"
11775         rm -f $DIR/$tfile
11776 }
11777 run_test 104a "lfs df [-ih] [path] test ========================="
11778
11779 test_104b() {
11780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11781         [ $RUNAS_ID -eq $UID ] &&
11782                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11783
11784         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11785                         grep "Permission denied" | wc -l)))
11786         if [ $denied_cnt -ne 0 ]; then
11787                 error "lfs check servers test failed"
11788         fi
11789 }
11790 run_test 104b "$RUNAS lfs check servers test ===================="
11791
11792 #
11793 # Verify $1 is within range of $2.
11794 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11795 # $1 is <= 2% of $2. Else Fail.
11796 #
11797 value_in_range() {
11798         # Strip all units (M, G, T)
11799         actual=$(echo $1 | tr -d A-Z)
11800         expect=$(echo $2 | tr -d A-Z)
11801
11802         expect_lo=$(($expect * 98 / 100)) # 2% below
11803         expect_hi=$(($expect * 102 / 100)) # 2% above
11804
11805         # permit 2% drift above and below
11806         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11807 }
11808
11809 test_104c() {
11810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11811         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11812
11813         local ost_param="osd-zfs.$FSNAME-OST0000."
11814         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11815         local ofacets=$(get_facets OST)
11816         local mfacets=$(get_facets MDS)
11817         local saved_ost_blocks=
11818         local saved_mdt_blocks=
11819
11820         echo "Before recordsize change"
11821         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11822         df=($(df -h | grep "$MOUNT"$))
11823
11824         # For checking.
11825         echo "lfs output : ${lfs_df[*]}"
11826         echo "df  output : ${df[*]}"
11827
11828         for facet in ${ofacets//,/ }; do
11829                 if [ -z $saved_ost_blocks ]; then
11830                         saved_ost_blocks=$(do_facet $facet \
11831                                 lctl get_param -n $ost_param.blocksize)
11832                         echo "OST Blocksize: $saved_ost_blocks"
11833                 fi
11834                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11835                 do_facet $facet zfs set recordsize=32768 $ost
11836         done
11837
11838         # BS too small. Sufficient for functional testing.
11839         for facet in ${mfacets//,/ }; do
11840                 if [ -z $saved_mdt_blocks ]; then
11841                         saved_mdt_blocks=$(do_facet $facet \
11842                                 lctl get_param -n $mdt_param.blocksize)
11843                         echo "MDT Blocksize: $saved_mdt_blocks"
11844                 fi
11845                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11846                 do_facet $facet zfs set recordsize=32768 $mdt
11847         done
11848
11849         # Give new values chance to reflect change
11850         sleep 2
11851
11852         echo "After recordsize change"
11853         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11854         df_after=($(df -h | grep "$MOUNT"$))
11855
11856         # For checking.
11857         echo "lfs output : ${lfs_df_after[*]}"
11858         echo "df  output : ${df_after[*]}"
11859
11860         # Verify lfs df
11861         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11862                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11863         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11864                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11865         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11866                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11867
11868         # Verify df
11869         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11870                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11871         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11872                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11873         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11874                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11875
11876         # Restore MDT recordize back to original
11877         for facet in ${mfacets//,/ }; do
11878                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11879                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11880         done
11881
11882         # Restore OST recordize back to original
11883         for facet in ${ofacets//,/ }; do
11884                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11885                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11886         done
11887
11888         return 0
11889 }
11890 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11891
11892 test_105a() {
11893         # doesn't work on 2.4 kernels
11894         touch $DIR/$tfile
11895         if $(flock_is_enabled); then
11896                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11897         else
11898                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11899         fi
11900         rm -f $DIR/$tfile
11901 }
11902 run_test 105a "flock when mounted without -o flock test ========"
11903
11904 test_105b() {
11905         touch $DIR/$tfile
11906         if $(flock_is_enabled); then
11907                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11908         else
11909                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11910         fi
11911         rm -f $DIR/$tfile
11912 }
11913 run_test 105b "fcntl when mounted without -o flock test ========"
11914
11915 test_105c() {
11916         touch $DIR/$tfile
11917         if $(flock_is_enabled); then
11918                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11919         else
11920                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11921         fi
11922         rm -f $DIR/$tfile
11923 }
11924 run_test 105c "lockf when mounted without -o flock test"
11925
11926 test_105d() { # bug 15924
11927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11928
11929         test_mkdir $DIR/$tdir
11930         flock_is_enabled || skip_env "mount w/o flock enabled"
11931         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11932         $LCTL set_param fail_loc=0x80000315
11933         flocks_test 2 $DIR/$tdir
11934 }
11935 run_test 105d "flock race (should not freeze) ========"
11936
11937 test_105e() { # bug 22660 && 22040
11938         flock_is_enabled || skip_env "mount w/o flock enabled"
11939
11940         touch $DIR/$tfile
11941         flocks_test 3 $DIR/$tfile
11942 }
11943 run_test 105e "Two conflicting flocks from same process"
11944
11945 test_106() { #bug 10921
11946         test_mkdir $DIR/$tdir
11947         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11948         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11949 }
11950 run_test 106 "attempt exec of dir followed by chown of that dir"
11951
11952 test_107() {
11953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11954
11955         CDIR=`pwd`
11956         local file=core
11957
11958         cd $DIR
11959         rm -f $file
11960
11961         local save_pattern=$(sysctl -n kernel.core_pattern)
11962         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11963         sysctl -w kernel.core_pattern=$file
11964         sysctl -w kernel.core_uses_pid=0
11965
11966         ulimit -c unlimited
11967         sleep 60 &
11968         SLEEPPID=$!
11969
11970         sleep 1
11971
11972         kill -s 11 $SLEEPPID
11973         wait $SLEEPPID
11974         if [ -e $file ]; then
11975                 size=`stat -c%s $file`
11976                 [ $size -eq 0 ] && error "Fail to create core file $file"
11977         else
11978                 error "Fail to create core file $file"
11979         fi
11980         rm -f $file
11981         sysctl -w kernel.core_pattern=$save_pattern
11982         sysctl -w kernel.core_uses_pid=$save_uses_pid
11983         cd $CDIR
11984 }
11985 run_test 107 "Coredump on SIG"
11986
11987 test_110() {
11988         test_mkdir $DIR/$tdir
11989         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11990         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11991                 error "mkdir with 256 char should fail, but did not"
11992         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11993                 error "create with 255 char failed"
11994         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11995                 error "create with 256 char should fail, but did not"
11996
11997         ls -l $DIR/$tdir
11998         rm -rf $DIR/$tdir
11999 }
12000 run_test 110 "filename length checking"
12001
12002 #
12003 # Purpose: To verify dynamic thread (OSS) creation.
12004 #
12005 test_115() {
12006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12007         remote_ost_nodsh && skip "remote OST with nodsh"
12008
12009         # Lustre does not stop service threads once they are started.
12010         # Reset number of running threads to default.
12011         stopall
12012         setupall
12013
12014         local OSTIO_pre
12015         local save_params="$TMP/sanity-$TESTNAME.parameters"
12016
12017         # Get ll_ost_io count before I/O
12018         OSTIO_pre=$(do_facet ost1 \
12019                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
12020         # Exit if lustre is not running (ll_ost_io not running).
12021         [ -z "$OSTIO_pre" ] && error "no OSS threads"
12022
12023         echo "Starting with $OSTIO_pre threads"
12024         local thread_max=$((OSTIO_pre * 2))
12025         local rpc_in_flight=$((thread_max * 2))
12026         # this is limited to OSC_MAX_RIF_MAX (256)
12027         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12028         thread_max=$((rpc_in_flight / 2))
12029         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12030                 return
12031
12032         # Number of I/O Process proposed to be started.
12033         local nfiles
12034         local facets=$(get_facets OST)
12035
12036         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12037         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12038
12039         # Set in_flight to $rpc_in_flight
12040         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12041                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12042         nfiles=${rpc_in_flight}
12043         # Set ost thread_max to $thread_max
12044         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12045
12046         # 5 Minutes should be sufficient for max number of OSS
12047         # threads(thread_max) to be created.
12048         local timeout=300
12049
12050         # Start I/O.
12051         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12052         test_mkdir $DIR/$tdir
12053         for i in $(seq $nfiles); do
12054                 local file=$DIR/$tdir/${tfile}-$i
12055                 $LFS setstripe -c -1 -i 0 $file
12056                 ($WTL $file $timeout)&
12057         done
12058
12059         # I/O Started - Wait for thread_started to reach thread_max or report
12060         # error if thread_started is more than thread_max.
12061         echo "Waiting for thread_started to reach thread_max"
12062         local thread_started=0
12063         local end_time=$((SECONDS + timeout))
12064
12065         while [ $SECONDS -le $end_time ] ; do
12066                 echo -n "."
12067                 # Get ost i/o thread_started count.
12068                 thread_started=$(do_facet ost1 \
12069                         "$LCTL get_param \
12070                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12071                 # Break out if thread_started is equal/greater than thread_max
12072                 if [[ $thread_started -ge $thread_max ]]; then
12073                         echo ll_ost_io thread_started $thread_started, \
12074                                 equal/greater than thread_max $thread_max
12075                         break
12076                 fi
12077                 sleep 1
12078         done
12079
12080         # Cleanup - We have the numbers, Kill i/o jobs if running.
12081         jobcount=($(jobs -p))
12082         for i in $(seq 0 $((${#jobcount[@]}-1)))
12083         do
12084                 kill -9 ${jobcount[$i]}
12085                 if [ $? -ne 0 ] ; then
12086                         echo Warning: \
12087                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12088                 fi
12089         done
12090
12091         # Cleanup files left by WTL binary.
12092         for i in $(seq $nfiles); do
12093                 local file=$DIR/$tdir/${tfile}-$i
12094                 rm -rf $file
12095                 if [ $? -ne 0 ] ; then
12096                         echo "Warning: Failed to delete file $file"
12097                 fi
12098         done
12099
12100         restore_lustre_params <$save_params
12101         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12102
12103         # Error out if no new thread has started or Thread started is greater
12104         # than thread max.
12105         if [[ $thread_started -le $OSTIO_pre ||
12106                         $thread_started -gt $thread_max ]]; then
12107                 error "ll_ost_io: thread_started $thread_started" \
12108                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12109                       "No new thread started or thread started greater " \
12110                       "than thread_max."
12111         fi
12112 }
12113 run_test 115 "verify dynamic thread creation===================="
12114
12115 test_116a() { # was previously test_116()
12116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12117         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12118         remote_mds_nodsh && skip "remote MDS with nodsh"
12119
12120         echo -n "Free space priority "
12121         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12122                 head -n1
12123         declare -a AVAIL
12124         free_min_max
12125
12126         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12127         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12128         stack_trap simple_cleanup_common
12129
12130         # Check if we need to generate uneven OSTs
12131         test_mkdir -p $DIR/$tdir/OST${MINI}
12132         local FILL=$((MINV / 4))
12133         local DIFF=$((MAXV - MINV))
12134         local DIFF2=$((DIFF * 100 / MINV))
12135
12136         local threshold=$(do_facet $SINGLEMDS \
12137                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12138         threshold=${threshold%%%}
12139         echo -n "Check for uneven OSTs: "
12140         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12141
12142         if [[ $DIFF2 -gt $threshold ]]; then
12143                 echo "ok"
12144                 echo "Don't need to fill OST$MINI"
12145         else
12146                 # generate uneven OSTs. Write 2% over the QOS threshold value
12147                 echo "no"
12148                 DIFF=$((threshold - DIFF2 + 2))
12149                 DIFF2=$((MINV * DIFF / 100))
12150                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12151                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12152                         error "setstripe failed"
12153                 DIFF=$((DIFF2 / 2048))
12154                 i=0
12155                 while [ $i -lt $DIFF ]; do
12156                         i=$((i + 1))
12157                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12158                                 bs=2M count=1 2>/dev/null
12159                         echo -n .
12160                 done
12161                 echo .
12162                 sync
12163                 sleep_maxage
12164                 free_min_max
12165         fi
12166
12167         DIFF=$((MAXV - MINV))
12168         DIFF2=$((DIFF * 100 / MINV))
12169         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12170         if [ $DIFF2 -gt $threshold ]; then
12171                 echo "ok"
12172         else
12173                 skip "QOS imbalance criteria not met"
12174         fi
12175
12176         MINI1=$MINI
12177         MINV1=$MINV
12178         MAXI1=$MAXI
12179         MAXV1=$MAXV
12180
12181         # now fill using QOS
12182         $LFS setstripe -c 1 $DIR/$tdir
12183         FILL=$((FILL / 200))
12184         if [ $FILL -gt 600 ]; then
12185                 FILL=600
12186         fi
12187         echo "writing $FILL files to QOS-assigned OSTs"
12188         i=0
12189         while [ $i -lt $FILL ]; do
12190                 i=$((i + 1))
12191                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12192                         count=1 2>/dev/null
12193                 echo -n .
12194         done
12195         echo "wrote $i 200k files"
12196         sync
12197         sleep_maxage
12198
12199         echo "Note: free space may not be updated, so measurements might be off"
12200         free_min_max
12201         DIFF2=$((MAXV - MINV))
12202         echo "free space delta: orig $DIFF final $DIFF2"
12203         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12204         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12205         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12206         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12207         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12208         if [[ $DIFF -gt 0 ]]; then
12209                 FILL=$((DIFF2 * 100 / DIFF - 100))
12210                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12211         fi
12212
12213         # Figure out which files were written where
12214         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12215                awk '/'$MINI1': / {print $2; exit}')
12216         echo $UUID
12217         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12218         echo "$MINC files created on smaller OST $MINI1"
12219         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12220                awk '/'$MAXI1': / {print $2; exit}')
12221         echo $UUID
12222         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12223         echo "$MAXC files created on larger OST $MAXI1"
12224         if [[ $MINC -gt 0 ]]; then
12225                 FILL=$((MAXC * 100 / MINC - 100))
12226                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12227         fi
12228         [[ $MAXC -gt $MINC ]] ||
12229                 error_ignore LU-9 "stripe QOS didn't balance free space"
12230 }
12231 run_test 116a "stripe QOS: free space balance ==================="
12232
12233 test_116b() { # LU-2093
12234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12235         remote_mds_nodsh && skip "remote MDS with nodsh"
12236
12237 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12238         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12239                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12240         [ -z "$old_rr" ] && skip "no QOS"
12241         do_facet $SINGLEMDS lctl set_param \
12242                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12243         mkdir -p $DIR/$tdir
12244         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12245         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12246         do_facet $SINGLEMDS lctl set_param fail_loc=0
12247         rm -rf $DIR/$tdir
12248         do_facet $SINGLEMDS lctl set_param \
12249                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12250 }
12251 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12252
12253 test_117() # bug 10891
12254 {
12255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12256
12257         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12258         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12259         lctl set_param fail_loc=0x21e
12260         > $DIR/$tfile || error "truncate failed"
12261         lctl set_param fail_loc=0
12262         echo "Truncate succeeded."
12263         rm -f $DIR/$tfile
12264 }
12265 run_test 117 "verify osd extend =========="
12266
12267 NO_SLOW_RESENDCOUNT=4
12268 export OLD_RESENDCOUNT=""
12269 set_resend_count () {
12270         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12271         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12272         lctl set_param -n $PROC_RESENDCOUNT $1
12273         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12274 }
12275
12276 # for reduce test_118* time (b=14842)
12277 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12278
12279 # Reset async IO behavior after error case
12280 reset_async() {
12281         FILE=$DIR/reset_async
12282
12283         # Ensure all OSCs are cleared
12284         $LFS setstripe -c -1 $FILE
12285         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12286         sync
12287         rm $FILE
12288 }
12289
12290 test_118a() #bug 11710
12291 {
12292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12293
12294         reset_async
12295
12296         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12297         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12298         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12299
12300         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12301                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12302                 return 1;
12303         fi
12304         rm -f $DIR/$tfile
12305 }
12306 run_test 118a "verify O_SYNC works =========="
12307
12308 test_118b()
12309 {
12310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12311         remote_ost_nodsh && skip "remote OST with nodsh"
12312
12313         reset_async
12314
12315         #define OBD_FAIL_SRV_ENOENT 0x217
12316         set_nodes_failloc "$(osts_nodes)" 0x217
12317         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12318         RC=$?
12319         set_nodes_failloc "$(osts_nodes)" 0
12320         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12321         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12322                     grep -c writeback)
12323
12324         if [[ $RC -eq 0 ]]; then
12325                 error "Must return error due to dropped pages, rc=$RC"
12326                 return 1;
12327         fi
12328
12329         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12330                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12331                 return 1;
12332         fi
12333
12334         echo "Dirty pages not leaked on ENOENT"
12335
12336         # Due to the above error the OSC will issue all RPCs syncronously
12337         # until a subsequent RPC completes successfully without error.
12338         $MULTIOP $DIR/$tfile Ow4096yc
12339         rm -f $DIR/$tfile
12340
12341         return 0
12342 }
12343 run_test 118b "Reclaim dirty pages on fatal error =========="
12344
12345 test_118c()
12346 {
12347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12348
12349         # for 118c, restore the original resend count, LU-1940
12350         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12351                                 set_resend_count $OLD_RESENDCOUNT
12352         remote_ost_nodsh && skip "remote OST with nodsh"
12353
12354         reset_async
12355
12356         #define OBD_FAIL_OST_EROFS               0x216
12357         set_nodes_failloc "$(osts_nodes)" 0x216
12358
12359         # multiop should block due to fsync until pages are written
12360         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12361         MULTIPID=$!
12362         sleep 1
12363
12364         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12365                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12366         fi
12367
12368         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12369                     grep -c writeback)
12370         if [[ $WRITEBACK -eq 0 ]]; then
12371                 error "No page in writeback, writeback=$WRITEBACK"
12372         fi
12373
12374         set_nodes_failloc "$(osts_nodes)" 0
12375         wait $MULTIPID
12376         RC=$?
12377         if [[ $RC -ne 0 ]]; then
12378                 error "Multiop fsync failed, rc=$RC"
12379         fi
12380
12381         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12382         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12383                     grep -c writeback)
12384         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12385                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12386         fi
12387
12388         rm -f $DIR/$tfile
12389         echo "Dirty pages flushed via fsync on EROFS"
12390         return 0
12391 }
12392 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12393
12394 # continue to use small resend count to reduce test_118* time (b=14842)
12395 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12396
12397 test_118d()
12398 {
12399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12400         remote_ost_nodsh && skip "remote OST with nodsh"
12401
12402         reset_async
12403
12404         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12405         set_nodes_failloc "$(osts_nodes)" 0x214
12406         # multiop should block due to fsync until pages are written
12407         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12408         MULTIPID=$!
12409         sleep 1
12410
12411         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12412                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12413         fi
12414
12415         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12416                     grep -c writeback)
12417         if [[ $WRITEBACK -eq 0 ]]; then
12418                 error "No page in writeback, writeback=$WRITEBACK"
12419         fi
12420
12421         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12422         set_nodes_failloc "$(osts_nodes)" 0
12423
12424         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12425         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12426                     grep -c writeback)
12427         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12428                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12429         fi
12430
12431         rm -f $DIR/$tfile
12432         echo "Dirty pages gaurenteed flushed via fsync"
12433         return 0
12434 }
12435 run_test 118d "Fsync validation inject a delay of the bulk =========="
12436
12437 test_118f() {
12438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12439
12440         reset_async
12441
12442         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12443         lctl set_param fail_loc=0x8000040a
12444
12445         # Should simulate EINVAL error which is fatal
12446         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12447         RC=$?
12448         if [[ $RC -eq 0 ]]; then
12449                 error "Must return error due to dropped pages, rc=$RC"
12450         fi
12451
12452         lctl set_param fail_loc=0x0
12453
12454         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12455         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12456         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12457                     grep -c writeback)
12458         if [[ $LOCKED -ne 0 ]]; then
12459                 error "Locked pages remain in cache, locked=$LOCKED"
12460         fi
12461
12462         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12463                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12464         fi
12465
12466         rm -f $DIR/$tfile
12467         echo "No pages locked after fsync"
12468
12469         reset_async
12470         return 0
12471 }
12472 run_test 118f "Simulate unrecoverable OSC side error =========="
12473
12474 test_118g() {
12475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12476
12477         reset_async
12478
12479         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12480         lctl set_param fail_loc=0x406
12481
12482         # simulate local -ENOMEM
12483         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12484         RC=$?
12485
12486         lctl set_param fail_loc=0
12487         if [[ $RC -eq 0 ]]; then
12488                 error "Must return error due to dropped pages, rc=$RC"
12489         fi
12490
12491         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12492         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12493         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12494                         grep -c writeback)
12495         if [[ $LOCKED -ne 0 ]]; then
12496                 error "Locked pages remain in cache, locked=$LOCKED"
12497         fi
12498
12499         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12500                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12501         fi
12502
12503         rm -f $DIR/$tfile
12504         echo "No pages locked after fsync"
12505
12506         reset_async
12507         return 0
12508 }
12509 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12510
12511 test_118h() {
12512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12513         remote_ost_nodsh && skip "remote OST with nodsh"
12514
12515         reset_async
12516
12517         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12518         set_nodes_failloc "$(osts_nodes)" 0x20e
12519         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12520         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12521         RC=$?
12522
12523         set_nodes_failloc "$(osts_nodes)" 0
12524         if [[ $RC -eq 0 ]]; then
12525                 error "Must return error due to dropped pages, rc=$RC"
12526         fi
12527
12528         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12529         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12530         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12531                     grep -c writeback)
12532         if [[ $LOCKED -ne 0 ]]; then
12533                 error "Locked pages remain in cache, locked=$LOCKED"
12534         fi
12535
12536         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12537                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12538         fi
12539
12540         rm -f $DIR/$tfile
12541         echo "No pages locked after fsync"
12542
12543         return 0
12544 }
12545 run_test 118h "Verify timeout in handling recoverables errors  =========="
12546
12547 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12548
12549 test_118i() {
12550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12551         remote_ost_nodsh && skip "remote OST with nodsh"
12552
12553         reset_async
12554
12555         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12556         set_nodes_failloc "$(osts_nodes)" 0x20e
12557
12558         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12559         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12560         PID=$!
12561         sleep 5
12562         set_nodes_failloc "$(osts_nodes)" 0
12563
12564         wait $PID
12565         RC=$?
12566         if [[ $RC -ne 0 ]]; then
12567                 error "got error, but should be not, rc=$RC"
12568         fi
12569
12570         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12571         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12572         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12573         if [[ $LOCKED -ne 0 ]]; then
12574                 error "Locked pages remain in cache, locked=$LOCKED"
12575         fi
12576
12577         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12578                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12579         fi
12580
12581         rm -f $DIR/$tfile
12582         echo "No pages locked after fsync"
12583
12584         return 0
12585 }
12586 run_test 118i "Fix error before timeout in recoverable error  =========="
12587
12588 [ "$SLOW" = "no" ] && set_resend_count 4
12589
12590 test_118j() {
12591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12592         remote_ost_nodsh && skip "remote OST with nodsh"
12593
12594         reset_async
12595
12596         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12597         set_nodes_failloc "$(osts_nodes)" 0x220
12598
12599         # return -EIO from OST
12600         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12601         RC=$?
12602         set_nodes_failloc "$(osts_nodes)" 0x0
12603         if [[ $RC -eq 0 ]]; then
12604                 error "Must return error due to dropped pages, rc=$RC"
12605         fi
12606
12607         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12608         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12609         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12610         if [[ $LOCKED -ne 0 ]]; then
12611                 error "Locked pages remain in cache, locked=$LOCKED"
12612         fi
12613
12614         # in recoverable error on OST we want resend and stay until it finished
12615         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12616                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12617         fi
12618
12619         rm -f $DIR/$tfile
12620         echo "No pages locked after fsync"
12621
12622         return 0
12623 }
12624 run_test 118j "Simulate unrecoverable OST side error =========="
12625
12626 test_118k()
12627 {
12628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12629         remote_ost_nodsh && skip "remote OSTs with nodsh"
12630
12631         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12632         set_nodes_failloc "$(osts_nodes)" 0x20e
12633         test_mkdir $DIR/$tdir
12634
12635         for ((i=0;i<10;i++)); do
12636                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12637                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12638                 SLEEPPID=$!
12639                 sleep 0.500s
12640                 kill $SLEEPPID
12641                 wait $SLEEPPID
12642         done
12643
12644         set_nodes_failloc "$(osts_nodes)" 0
12645         rm -rf $DIR/$tdir
12646 }
12647 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12648
12649 test_118l() # LU-646
12650 {
12651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12652
12653         test_mkdir $DIR/$tdir
12654         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12655         rm -rf $DIR/$tdir
12656 }
12657 run_test 118l "fsync dir"
12658
12659 test_118m() # LU-3066
12660 {
12661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12662
12663         test_mkdir $DIR/$tdir
12664         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12665         rm -rf $DIR/$tdir
12666 }
12667 run_test 118m "fdatasync dir ========="
12668
12669 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12670
12671 test_118n()
12672 {
12673         local begin
12674         local end
12675
12676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12677         remote_ost_nodsh && skip "remote OSTs with nodsh"
12678
12679         # Sleep to avoid a cached response.
12680         #define OBD_STATFS_CACHE_SECONDS 1
12681         sleep 2
12682
12683         # Inject a 10 second delay in the OST_STATFS handler.
12684         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12685         set_nodes_failloc "$(osts_nodes)" 0x242
12686
12687         begin=$SECONDS
12688         stat --file-system $MOUNT > /dev/null
12689         end=$SECONDS
12690
12691         set_nodes_failloc "$(osts_nodes)" 0
12692
12693         if ((end - begin > 20)); then
12694             error "statfs took $((end - begin)) seconds, expected 10"
12695         fi
12696 }
12697 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12698
12699 test_119a() # bug 11737
12700 {
12701         BSIZE=$((512 * 1024))
12702         directio write $DIR/$tfile 0 1 $BSIZE
12703         # We ask to read two blocks, which is more than a file size.
12704         # directio will indicate an error when requested and actual
12705         # sizes aren't equeal (a normal situation in this case) and
12706         # print actual read amount.
12707         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12708         if [ "$NOB" != "$BSIZE" ]; then
12709                 error "read $NOB bytes instead of $BSIZE"
12710         fi
12711         rm -f $DIR/$tfile
12712 }
12713 run_test 119a "Short directIO read must return actual read amount"
12714
12715 test_119b() # bug 11737
12716 {
12717         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12718
12719         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12720         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12721         sync
12722         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12723                 error "direct read failed"
12724         rm -f $DIR/$tfile
12725 }
12726 run_test 119b "Sparse directIO read must return actual read amount"
12727
12728 test_119c() # bug 13099
12729 {
12730         BSIZE=1048576
12731         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12732         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12733         rm -f $DIR/$tfile
12734 }
12735 run_test 119c "Testing for direct read hitting hole"
12736
12737 test_119d() # bug 15950
12738 {
12739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12740
12741         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12742         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12743         BSIZE=1048576
12744         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12745         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12746         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12747         lctl set_param fail_loc=0x40d
12748         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12749         pid_dio=$!
12750         sleep 1
12751         cat $DIR/$tfile > /dev/null &
12752         lctl set_param fail_loc=0
12753         pid_reads=$!
12754         wait $pid_dio
12755         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12756         sleep 2
12757         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12758         error "the read rpcs have not completed in 2s"
12759         rm -f $DIR/$tfile
12760         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12761 }
12762 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12763
12764 test_120a() {
12765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12766         remote_mds_nodsh && skip "remote MDS with nodsh"
12767         test_mkdir -i0 -c1 $DIR/$tdir
12768         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12769                 skip_env "no early lock cancel on server"
12770
12771         lru_resize_disable mdc
12772         lru_resize_disable osc
12773         cancel_lru_locks mdc
12774         # asynchronous object destroy at MDT could cause bl ast to client
12775         cancel_lru_locks osc
12776
12777         stat $DIR/$tdir > /dev/null
12778         can1=$(do_facet mds1 \
12779                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12780                awk '/ldlm_cancel/ {print $2}')
12781         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12782                awk '/ldlm_bl_callback/ {print $2}')
12783         test_mkdir -i0 -c1 $DIR/$tdir/d1
12784         can2=$(do_facet mds1 \
12785                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12786                awk '/ldlm_cancel/ {print $2}')
12787         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12788                awk '/ldlm_bl_callback/ {print $2}')
12789         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12790         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12791         lru_resize_enable mdc
12792         lru_resize_enable osc
12793 }
12794 run_test 120a "Early Lock Cancel: mkdir test"
12795
12796 test_120b() {
12797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12798         remote_mds_nodsh && skip "remote MDS with nodsh"
12799         test_mkdir $DIR/$tdir
12800         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12801                 skip_env "no early lock cancel on server"
12802
12803         lru_resize_disable mdc
12804         lru_resize_disable osc
12805         cancel_lru_locks mdc
12806         stat $DIR/$tdir > /dev/null
12807         can1=$(do_facet $SINGLEMDS \
12808                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12809                awk '/ldlm_cancel/ {print $2}')
12810         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12811                awk '/ldlm_bl_callback/ {print $2}')
12812         touch $DIR/$tdir/f1
12813         can2=$(do_facet $SINGLEMDS \
12814                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12815                awk '/ldlm_cancel/ {print $2}')
12816         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12817                awk '/ldlm_bl_callback/ {print $2}')
12818         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12819         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12820         lru_resize_enable mdc
12821         lru_resize_enable osc
12822 }
12823 run_test 120b "Early Lock Cancel: create test"
12824
12825 test_120c() {
12826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12827         remote_mds_nodsh && skip "remote MDS with nodsh"
12828         test_mkdir -i0 -c1 $DIR/$tdir
12829         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12830                 skip "no early lock cancel on server"
12831
12832         lru_resize_disable mdc
12833         lru_resize_disable osc
12834         test_mkdir -i0 -c1 $DIR/$tdir/d1
12835         test_mkdir -i0 -c1 $DIR/$tdir/d2
12836         touch $DIR/$tdir/d1/f1
12837         cancel_lru_locks mdc
12838         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12839         can1=$(do_facet mds1 \
12840                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12841                awk '/ldlm_cancel/ {print $2}')
12842         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12843                awk '/ldlm_bl_callback/ {print $2}')
12844         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12845         can2=$(do_facet mds1 \
12846                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12847                awk '/ldlm_cancel/ {print $2}')
12848         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12849                awk '/ldlm_bl_callback/ {print $2}')
12850         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12851         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12852         lru_resize_enable mdc
12853         lru_resize_enable osc
12854 }
12855 run_test 120c "Early Lock Cancel: link test"
12856
12857 test_120d() {
12858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12859         remote_mds_nodsh && skip "remote MDS with nodsh"
12860         test_mkdir -i0 -c1 $DIR/$tdir
12861         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12862                 skip_env "no early lock cancel on server"
12863
12864         lru_resize_disable mdc
12865         lru_resize_disable osc
12866         touch $DIR/$tdir
12867         cancel_lru_locks mdc
12868         stat $DIR/$tdir > /dev/null
12869         can1=$(do_facet mds1 \
12870                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12871                awk '/ldlm_cancel/ {print $2}')
12872         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12873                awk '/ldlm_bl_callback/ {print $2}')
12874         chmod a+x $DIR/$tdir
12875         can2=$(do_facet mds1 \
12876                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12877                awk '/ldlm_cancel/ {print $2}')
12878         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12879                awk '/ldlm_bl_callback/ {print $2}')
12880         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12881         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12882         lru_resize_enable mdc
12883         lru_resize_enable osc
12884 }
12885 run_test 120d "Early Lock Cancel: setattr test"
12886
12887 test_120e() {
12888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12889         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12890                 skip_env "no early lock cancel on server"
12891         remote_mds_nodsh && skip "remote MDS with nodsh"
12892
12893         local dlmtrace_set=false
12894
12895         test_mkdir -i0 -c1 $DIR/$tdir
12896         lru_resize_disable mdc
12897         lru_resize_disable osc
12898         ! $LCTL get_param debug | grep -q dlmtrace &&
12899                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12900         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12901         cancel_lru_locks mdc
12902         cancel_lru_locks osc
12903         dd if=$DIR/$tdir/f1 of=/dev/null
12904         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12905         # XXX client can not do early lock cancel of OST lock
12906         # during unlink (LU-4206), so cancel osc lock now.
12907         sleep 2
12908         cancel_lru_locks osc
12909         can1=$(do_facet mds1 \
12910                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12911                awk '/ldlm_cancel/ {print $2}')
12912         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12913                awk '/ldlm_bl_callback/ {print $2}')
12914         unlink $DIR/$tdir/f1
12915         sleep 5
12916         can2=$(do_facet mds1 \
12917                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12918                awk '/ldlm_cancel/ {print $2}')
12919         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12920                awk '/ldlm_bl_callback/ {print $2}')
12921         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12922                 $LCTL dk $TMP/cancel.debug.txt
12923         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12924                 $LCTL dk $TMP/blocking.debug.txt
12925         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12926         lru_resize_enable mdc
12927         lru_resize_enable osc
12928 }
12929 run_test 120e "Early Lock Cancel: unlink test"
12930
12931 test_120f() {
12932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12933         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12934                 skip_env "no early lock cancel on server"
12935         remote_mds_nodsh && skip "remote MDS with nodsh"
12936
12937         test_mkdir -i0 -c1 $DIR/$tdir
12938         lru_resize_disable mdc
12939         lru_resize_disable osc
12940         test_mkdir -i0 -c1 $DIR/$tdir/d1
12941         test_mkdir -i0 -c1 $DIR/$tdir/d2
12942         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12943         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12944         cancel_lru_locks mdc
12945         cancel_lru_locks osc
12946         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12947         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12948         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12949         # XXX client can not do early lock cancel of OST lock
12950         # during rename (LU-4206), so cancel osc lock now.
12951         sleep 2
12952         cancel_lru_locks osc
12953         can1=$(do_facet mds1 \
12954                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12955                awk '/ldlm_cancel/ {print $2}')
12956         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12957                awk '/ldlm_bl_callback/ {print $2}')
12958         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12959         sleep 5
12960         can2=$(do_facet mds1 \
12961                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12962                awk '/ldlm_cancel/ {print $2}')
12963         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12964                awk '/ldlm_bl_callback/ {print $2}')
12965         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12966         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12967         lru_resize_enable mdc
12968         lru_resize_enable osc
12969 }
12970 run_test 120f "Early Lock Cancel: rename test"
12971
12972 test_120g() {
12973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12974         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12975                 skip_env "no early lock cancel on server"
12976         remote_mds_nodsh && skip "remote MDS with nodsh"
12977
12978         lru_resize_disable mdc
12979         lru_resize_disable osc
12980         count=10000
12981         echo create $count files
12982         test_mkdir $DIR/$tdir
12983         cancel_lru_locks mdc
12984         cancel_lru_locks osc
12985         t0=$(date +%s)
12986
12987         can0=$(do_facet $SINGLEMDS \
12988                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12989                awk '/ldlm_cancel/ {print $2}')
12990         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12991                awk '/ldlm_bl_callback/ {print $2}')
12992         createmany -o $DIR/$tdir/f $count
12993         sync
12994         can1=$(do_facet $SINGLEMDS \
12995                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12996                awk '/ldlm_cancel/ {print $2}')
12997         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12998                awk '/ldlm_bl_callback/ {print $2}')
12999         t1=$(date +%s)
13000         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13001         echo rm $count files
13002         rm -r $DIR/$tdir
13003         sync
13004         can2=$(do_facet $SINGLEMDS \
13005                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13006                awk '/ldlm_cancel/ {print $2}')
13007         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13008                awk '/ldlm_bl_callback/ {print $2}')
13009         t2=$(date +%s)
13010         echo total: $count removes in $((t2-t1))
13011         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13012         sleep 2
13013         # wait for commitment of removal
13014         lru_resize_enable mdc
13015         lru_resize_enable osc
13016 }
13017 run_test 120g "Early Lock Cancel: performance test"
13018
13019 test_121() { #bug #10589
13020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13021
13022         rm -rf $DIR/$tfile
13023         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13024 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13025         lctl set_param fail_loc=0x310
13026         cancel_lru_locks osc > /dev/null
13027         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13028         lctl set_param fail_loc=0
13029         [[ $reads -eq $writes ]] ||
13030                 error "read $reads blocks, must be $writes blocks"
13031 }
13032 run_test 121 "read cancel race ========="
13033
13034 test_123a_base() { # was test 123, statahead(bug 11401)
13035         local lsx="$1"
13036
13037         SLOWOK=0
13038         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13039                 log "testing UP system. Performance may be lower than expected."
13040                 SLOWOK=1
13041         fi
13042         running_in_vm && SLOWOK=1
13043
13044         rm -rf $DIR/$tdir
13045         test_mkdir $DIR/$tdir
13046         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13047         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13048         MULT=10
13049         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13050                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13051
13052                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13053                 lctl set_param -n llite.*.statahead_max 0
13054                 lctl get_param llite.*.statahead_max
13055                 cancel_lru_locks mdc
13056                 cancel_lru_locks osc
13057                 stime=$(date +%s)
13058                 time $lsx $DIR/$tdir | wc -l
13059                 etime=$(date +%s)
13060                 delta=$((etime - stime))
13061                 log "$lsx $i files without statahead: $delta sec"
13062                 lctl set_param llite.*.statahead_max=$max
13063
13064                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13065                         grep "statahead wrong:" | awk '{print $3}')
13066                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13067                 cancel_lru_locks mdc
13068                 cancel_lru_locks osc
13069                 stime=$(date +%s)
13070                 time $lsx $DIR/$tdir | wc -l
13071                 etime=$(date +%s)
13072                 delta_sa=$((etime - stime))
13073                 log "$lsx $i files with statahead: $delta_sa sec"
13074                 lctl get_param -n llite.*.statahead_stats
13075                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13076                         grep "statahead wrong:" | awk '{print $3}')
13077
13078                 [[ $swrong -lt $ewrong ]] &&
13079                         log "statahead was stopped, maybe too many locks held!"
13080                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13081
13082                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
13083                         max=$(lctl get_param -n llite.*.statahead_max |
13084                                 head -n 1)
13085                         lctl set_param -n llite.*.statahead_max 0
13086                         lctl get_param llite.*.statahead_max
13087                         cancel_lru_locks mdc
13088                         cancel_lru_locks osc
13089                         stime=$(date +%s)
13090                         time $lsx $DIR/$tdir | wc -l
13091                         etime=$(date +%s)
13092                         delta=$((etime - stime))
13093                         log "$lsx $i files again without statahead: $delta sec"
13094                         lctl set_param llite.*.statahead_max=$max
13095                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
13096                                 if [  $SLOWOK -eq 0 ]; then
13097                                         error "$lsx $i files is slower with statahead!"
13098                                 else
13099                                         log "$lsx $i files is slower with statahead!"
13100                                 fi
13101                                 break
13102                         fi
13103                 fi
13104
13105                 [ $delta -gt 20 ] && break
13106                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13107                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13108         done
13109         log "$lsx done"
13110
13111         stime=$(date +%s)
13112         rm -r $DIR/$tdir
13113         sync
13114         etime=$(date +%s)
13115         delta=$((etime - stime))
13116         log "rm -r $DIR/$tdir/: $delta seconds"
13117         log "rm done"
13118         lctl get_param -n llite.*.statahead_stats
13119 }
13120
13121 test_123aa() {
13122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13123
13124         test_123a_base "ls -l"
13125 }
13126 run_test 123aa "verify statahead work"
13127
13128 test_123ab() {
13129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13130
13131         statx_supported || skip_env "Test must be statx() syscall supported"
13132
13133         test_123a_base "$STATX -l"
13134 }
13135 run_test 123ab "verify statahead work by using statx"
13136
13137 test_123ac() {
13138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13139
13140         statx_supported || skip_env "Test must be statx() syscall supported"
13141
13142         local rpcs_before
13143         local rpcs_after
13144         local agl_before
13145         local agl_after
13146
13147         cancel_lru_locks $OSC
13148         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13149         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13150                 awk '/agl.total:/ {print $3}')
13151         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13152         test_123a_base "$STATX --cached=always -D"
13153         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13154                 awk '/agl.total:/ {print $3}')
13155         [ $agl_before -eq $agl_after ] ||
13156                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13157         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13158         [ $rpcs_after -eq $rpcs_before ] ||
13159                 error "$STATX should not send glimpse RPCs to $OSC"
13160 }
13161 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13162
13163 test_123b () { # statahead(bug 15027)
13164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13165
13166         test_mkdir $DIR/$tdir
13167         createmany -o $DIR/$tdir/$tfile-%d 1000
13168
13169         cancel_lru_locks mdc
13170         cancel_lru_locks osc
13171
13172 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13173         lctl set_param fail_loc=0x80000803
13174         ls -lR $DIR/$tdir > /dev/null
13175         log "ls done"
13176         lctl set_param fail_loc=0x0
13177         lctl get_param -n llite.*.statahead_stats
13178         rm -r $DIR/$tdir
13179         sync
13180
13181 }
13182 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13183
13184 test_123c() {
13185         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13186
13187         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13188         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13189         touch $DIR/$tdir.1/{1..3}
13190         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13191
13192         remount_client $MOUNT
13193
13194         $MULTIOP $DIR/$tdir.0 Q
13195
13196         # let statahead to complete
13197         ls -l $DIR/$tdir.0 > /dev/null
13198
13199         testid=$(echo $TESTNAME | tr '_' ' ')
13200         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13201                 error "statahead warning" || true
13202 }
13203 run_test 123c "Can not initialize inode warning on DNE statahead"
13204
13205 test_124a() {
13206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13207         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13208                 skip_env "no lru resize on server"
13209
13210         local NR=2000
13211
13212         test_mkdir $DIR/$tdir
13213
13214         log "create $NR files at $DIR/$tdir"
13215         createmany -o $DIR/$tdir/f $NR ||
13216                 error "failed to create $NR files in $DIR/$tdir"
13217
13218         cancel_lru_locks mdc
13219         ls -l $DIR/$tdir > /dev/null
13220
13221         local NSDIR=""
13222         local LRU_SIZE=0
13223         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13224                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13225                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13226                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13227                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13228                         log "NSDIR=$NSDIR"
13229                         log "NS=$(basename $NSDIR)"
13230                         break
13231                 fi
13232         done
13233
13234         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13235                 skip "Not enough cached locks created!"
13236         fi
13237         log "LRU=$LRU_SIZE"
13238
13239         local SLEEP=30
13240
13241         # We know that lru resize allows one client to hold $LIMIT locks
13242         # for 10h. After that locks begin to be killed by client.
13243         local MAX_HRS=10
13244         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13245         log "LIMIT=$LIMIT"
13246         if [ $LIMIT -lt $LRU_SIZE ]; then
13247                 skip "Limit is too small $LIMIT"
13248         fi
13249
13250         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13251         # killing locks. Some time was spent for creating locks. This means
13252         # that up to the moment of sleep finish we must have killed some of
13253         # them (10-100 locks). This depends on how fast ther were created.
13254         # Many of them were touched in almost the same moment and thus will
13255         # be killed in groups.
13256         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13257
13258         # Use $LRU_SIZE_B here to take into account real number of locks
13259         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13260         local LRU_SIZE_B=$LRU_SIZE
13261         log "LVF=$LVF"
13262         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13263         log "OLD_LVF=$OLD_LVF"
13264         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13265
13266         # Let's make sure that we really have some margin. Client checks
13267         # cached locks every 10 sec.
13268         SLEEP=$((SLEEP+20))
13269         log "Sleep ${SLEEP} sec"
13270         local SEC=0
13271         while ((SEC<$SLEEP)); do
13272                 echo -n "..."
13273                 sleep 5
13274                 SEC=$((SEC+5))
13275                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13276                 echo -n "$LRU_SIZE"
13277         done
13278         echo ""
13279         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13280         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13281
13282         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13283                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13284                 unlinkmany $DIR/$tdir/f $NR
13285                 return
13286         }
13287
13288         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13289         log "unlink $NR files at $DIR/$tdir"
13290         unlinkmany $DIR/$tdir/f $NR
13291 }
13292 run_test 124a "lru resize ======================================="
13293
13294 get_max_pool_limit()
13295 {
13296         local limit=$($LCTL get_param \
13297                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13298         local max=0
13299         for l in $limit; do
13300                 if [[ $l -gt $max ]]; then
13301                         max=$l
13302                 fi
13303         done
13304         echo $max
13305 }
13306
13307 test_124b() {
13308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13309         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13310                 skip_env "no lru resize on server"
13311
13312         LIMIT=$(get_max_pool_limit)
13313
13314         NR=$(($(default_lru_size)*20))
13315         if [[ $NR -gt $LIMIT ]]; then
13316                 log "Limit lock number by $LIMIT locks"
13317                 NR=$LIMIT
13318         fi
13319
13320         IFree=$(mdsrate_inodes_available)
13321         if [ $IFree -lt $NR ]; then
13322                 log "Limit lock number by $IFree inodes"
13323                 NR=$IFree
13324         fi
13325
13326         lru_resize_disable mdc
13327         test_mkdir -p $DIR/$tdir/disable_lru_resize
13328
13329         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13330         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13331         cancel_lru_locks mdc
13332         stime=`date +%s`
13333         PID=""
13334         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13335         PID="$PID $!"
13336         sleep 2
13337         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13338         PID="$PID $!"
13339         sleep 2
13340         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13341         PID="$PID $!"
13342         wait $PID
13343         etime=`date +%s`
13344         nolruresize_delta=$((etime-stime))
13345         log "ls -la time: $nolruresize_delta seconds"
13346         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13347         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13348
13349         lru_resize_enable mdc
13350         test_mkdir -p $DIR/$tdir/enable_lru_resize
13351
13352         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13353         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13354         cancel_lru_locks mdc
13355         stime=`date +%s`
13356         PID=""
13357         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13358         PID="$PID $!"
13359         sleep 2
13360         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13361         PID="$PID $!"
13362         sleep 2
13363         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13364         PID="$PID $!"
13365         wait $PID
13366         etime=`date +%s`
13367         lruresize_delta=$((etime-stime))
13368         log "ls -la time: $lruresize_delta seconds"
13369         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13370
13371         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13372                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13373         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13374                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13375         else
13376                 log "lru resize performs the same with no lru resize"
13377         fi
13378         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13379 }
13380 run_test 124b "lru resize (performance test) ======================="
13381
13382 test_124c() {
13383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13384         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13385                 skip_env "no lru resize on server"
13386
13387         # cache ununsed locks on client
13388         local nr=100
13389         cancel_lru_locks mdc
13390         test_mkdir $DIR/$tdir
13391         createmany -o $DIR/$tdir/f $nr ||
13392                 error "failed to create $nr files in $DIR/$tdir"
13393         ls -l $DIR/$tdir > /dev/null
13394
13395         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13396         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13397         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13398         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13399         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13400
13401         # set lru_max_age to 1 sec
13402         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13403         echo "sleep $((recalc_p * 2)) seconds..."
13404         sleep $((recalc_p * 2))
13405
13406         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13407         # restore lru_max_age
13408         $LCTL set_param -n $nsdir.lru_max_age $max_age
13409         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13410         unlinkmany $DIR/$tdir/f $nr
13411 }
13412 run_test 124c "LRUR cancel very aged locks"
13413
13414 test_124d() {
13415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13416         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13417                 skip_env "no lru resize on server"
13418
13419         # cache ununsed locks on client
13420         local nr=100
13421
13422         lru_resize_disable mdc
13423         stack_trap "lru_resize_enable mdc" EXIT
13424
13425         cancel_lru_locks mdc
13426
13427         # asynchronous object destroy at MDT could cause bl ast to client
13428         test_mkdir $DIR/$tdir
13429         createmany -o $DIR/$tdir/f $nr ||
13430                 error "failed to create $nr files in $DIR/$tdir"
13431         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13432
13433         ls -l $DIR/$tdir > /dev/null
13434
13435         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13436         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13437         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13438         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13439
13440         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13441
13442         # set lru_max_age to 1 sec
13443         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13444         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13445
13446         echo "sleep $((recalc_p * 2)) seconds..."
13447         sleep $((recalc_p * 2))
13448
13449         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13450
13451         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13452 }
13453 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13454
13455 test_125() { # 13358
13456         $LCTL get_param -n llite.*.client_type | grep -q local ||
13457                 skip "must run as local client"
13458         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13459                 skip_env "must have acl enabled"
13460         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13461
13462         test_mkdir $DIR/$tdir
13463         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13464         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13465         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13466 }
13467 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13468
13469 test_126() { # bug 12829/13455
13470         $GSS && skip_env "must run as gss disabled"
13471         $LCTL get_param -n llite.*.client_type | grep -q local ||
13472                 skip "must run as local client"
13473         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13474
13475         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13476         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13477         rm -f $DIR/$tfile
13478         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13479 }
13480 run_test 126 "check that the fsgid provided by the client is taken into account"
13481
13482 test_127a() { # bug 15521
13483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13484         local name count samp unit min max sum sumsq
13485
13486         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13487         echo "stats before reset"
13488         $LCTL get_param osc.*.stats
13489         $LCTL set_param osc.*.stats=0
13490         local fsize=$((2048 * 1024))
13491
13492         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13493         cancel_lru_locks osc
13494         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13495
13496         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13497         stack_trap "rm -f $TMP/$tfile.tmp"
13498         while read name count samp unit min max sum sumsq; do
13499                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13500                 [ ! $min ] && error "Missing min value for $name proc entry"
13501                 eval $name=$count || error "Wrong proc format"
13502
13503                 case $name in
13504                 read_bytes|write_bytes)
13505                         [[ "$unit" =~ "bytes" ]] ||
13506                                 error "unit is not 'bytes': $unit"
13507                         (( $min >= 4096 )) || error "min is too small: $min"
13508                         (( $min <= $fsize )) || error "min is too big: $min"
13509                         (( $max >= 4096 )) || error "max is too small: $max"
13510                         (( $max <= $fsize )) || error "max is too big: $max"
13511                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13512                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13513                                 error "sumsquare is too small: $sumsq"
13514                         (( $sumsq <= $fsize * $fsize )) ||
13515                                 error "sumsquare is too big: $sumsq"
13516                         ;;
13517                 ost_read|ost_write)
13518                         [[ "$unit" =~ "usec" ]] ||
13519                                 error "unit is not 'usec': $unit"
13520                         ;;
13521                 *)      ;;
13522                 esac
13523         done < $DIR/$tfile.tmp
13524
13525         #check that we actually got some stats
13526         [ "$read_bytes" ] || error "Missing read_bytes stats"
13527         [ "$write_bytes" ] || error "Missing write_bytes stats"
13528         [ "$read_bytes" != 0 ] || error "no read done"
13529         [ "$write_bytes" != 0 ] || error "no write done"
13530 }
13531 run_test 127a "verify the client stats are sane"
13532
13533 test_127b() { # bug LU-333
13534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13535         local name count samp unit min max sum sumsq
13536
13537         echo "stats before reset"
13538         $LCTL get_param llite.*.stats
13539         $LCTL set_param llite.*.stats=0
13540
13541         # perform 2 reads and writes so MAX is different from SUM.
13542         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13543         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13544         cancel_lru_locks osc
13545         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13546         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13547
13548         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13549         stack_trap "rm -f $TMP/$tfile.tmp"
13550         while read name count samp unit min max sum sumsq; do
13551                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13552                 eval $name=$count || error "Wrong proc format"
13553
13554                 case $name in
13555                 read_bytes|write_bytes)
13556                         [[ "$unit" =~ "bytes" ]] ||
13557                                 error "unit is not 'bytes': $unit"
13558                         (( $count == 2 )) || error "count is not 2: $count"
13559                         (( $min == $PAGE_SIZE )) ||
13560                                 error "min is not $PAGE_SIZE: $min"
13561                         (( $max == $PAGE_SIZE )) ||
13562                                 error "max is not $PAGE_SIZE: $max"
13563                         (( $sum == $PAGE_SIZE * 2 )) ||
13564                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13565                         ;;
13566                 read|write)
13567                         [[ "$unit" =~ "usec" ]] ||
13568                                 error "unit is not 'usec': $unit"
13569                         ;;
13570                 *)      ;;
13571                 esac
13572         done < $TMP/$tfile.tmp
13573
13574         #check that we actually got some stats
13575         [ "$read_bytes" ] || error "Missing read_bytes stats"
13576         [ "$write_bytes" ] || error "Missing write_bytes stats"
13577         [ "$read_bytes" != 0 ] || error "no read done"
13578         [ "$write_bytes" != 0 ] || error "no write done"
13579 }
13580 run_test 127b "verify the llite client stats are sane"
13581
13582 test_127c() { # LU-12394
13583         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13584         local size
13585         local bsize
13586         local reads
13587         local writes
13588         local count
13589
13590         $LCTL set_param llite.*.extents_stats=1
13591         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13592
13593         # Use two stripes so there is enough space in default config
13594         $LFS setstripe -c 2 $DIR/$tfile
13595
13596         # Extent stats start at 0-4K and go in power of two buckets
13597         # LL_HIST_START = 12 --> 2^12 = 4K
13598         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13599         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13600         # small configs
13601         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13602                 do
13603                 # Write and read, 2x each, second time at a non-zero offset
13604                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13605                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13606                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13607                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13608                 rm -f $DIR/$tfile
13609         done
13610
13611         $LCTL get_param llite.*.extents_stats
13612
13613         count=2
13614         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13615                 do
13616                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13617                                 grep -m 1 $bsize)
13618                 reads=$(echo $bucket | awk '{print $5}')
13619                 writes=$(echo $bucket | awk '{print $9}')
13620                 [ "$reads" -eq $count ] ||
13621                         error "$reads reads in < $bsize bucket, expect $count"
13622                 [ "$writes" -eq $count ] ||
13623                         error "$writes writes in < $bsize bucket, expect $count"
13624         done
13625
13626         # Test mmap write and read
13627         $LCTL set_param llite.*.extents_stats=c
13628         size=512
13629         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13630         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13631         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13632
13633         $LCTL get_param llite.*.extents_stats
13634
13635         count=$(((size*1024) / PAGE_SIZE))
13636
13637         bsize=$((2 * PAGE_SIZE / 1024))K
13638
13639         bucket=$($LCTL get_param -n llite.*.extents_stats |
13640                         grep -m 1 $bsize)
13641         reads=$(echo $bucket | awk '{print $5}')
13642         writes=$(echo $bucket | awk '{print $9}')
13643         # mmap writes fault in the page first, creating an additonal read
13644         [ "$reads" -eq $((2 * count)) ] ||
13645                 error "$reads reads in < $bsize bucket, expect $count"
13646         [ "$writes" -eq $count ] ||
13647                 error "$writes writes in < $bsize bucket, expect $count"
13648 }
13649 run_test 127c "test llite extent stats with regular & mmap i/o"
13650
13651 test_128() { # bug 15212
13652         touch $DIR/$tfile
13653         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13654                 find $DIR/$tfile
13655                 find $DIR/$tfile
13656         EOF
13657
13658         result=$(grep error $TMP/$tfile.log)
13659         rm -f $DIR/$tfile $TMP/$tfile.log
13660         [ -z "$result" ] ||
13661                 error "consecutive find's under interactive lfs failed"
13662 }
13663 run_test 128 "interactive lfs for 2 consecutive find's"
13664
13665 set_dir_limits () {
13666         local mntdev
13667         local canondev
13668         local node
13669
13670         local ldproc=/proc/fs/ldiskfs
13671         local facets=$(get_facets MDS)
13672
13673         for facet in ${facets//,/ }; do
13674                 canondev=$(ldiskfs_canon \
13675                            *.$(convert_facet2label $facet).mntdev $facet)
13676                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13677                         ldproc=/sys/fs/ldiskfs
13678                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13679                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13680         done
13681 }
13682
13683 check_mds_dmesg() {
13684         local facets=$(get_facets MDS)
13685         for facet in ${facets//,/ }; do
13686                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13687         done
13688         return 1
13689 }
13690
13691 test_129() {
13692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13693         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13694                 skip "Need MDS version with at least 2.5.56"
13695         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13696                 skip_env "ldiskfs only test"
13697         fi
13698         remote_mds_nodsh && skip "remote MDS with nodsh"
13699
13700         local ENOSPC=28
13701         local has_warning=false
13702
13703         rm -rf $DIR/$tdir
13704         mkdir -p $DIR/$tdir
13705
13706         # block size of mds1
13707         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13708         set_dir_limits $maxsize $((maxsize * 6 / 8))
13709         stack_trap "set_dir_limits 0 0"
13710         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13711         local dirsize=$(stat -c%s "$DIR/$tdir")
13712         local nfiles=0
13713         while (( $dirsize <= $maxsize )); do
13714                 $MCREATE $DIR/$tdir/file_base_$nfiles
13715                 rc=$?
13716                 # check two errors:
13717                 # ENOSPC for ext4 max_dir_size, which has been used since
13718                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13719                 if (( rc == ENOSPC )); then
13720                         set_dir_limits 0 0
13721                         echo "rc=$rc returned as expected after $nfiles files"
13722
13723                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13724                                 error "create failed w/o dir size limit"
13725
13726                         # messages may be rate limited if test is run repeatedly
13727                         check_mds_dmesg '"is approaching max"' ||
13728                                 echo "warning message should be output"
13729                         check_mds_dmesg '"has reached max"' ||
13730                                 echo "reached message should be output"
13731
13732                         dirsize=$(stat -c%s "$DIR/$tdir")
13733
13734                         [[ $dirsize -ge $maxsize ]] && return 0
13735                         error "dirsize $dirsize < $maxsize after $nfiles files"
13736                 elif (( rc != 0 )); then
13737                         break
13738                 fi
13739                 nfiles=$((nfiles + 1))
13740                 dirsize=$(stat -c%s "$DIR/$tdir")
13741         done
13742
13743         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13744 }
13745 run_test 129 "test directory size limit ========================"
13746
13747 OLDIFS="$IFS"
13748 cleanup_130() {
13749         trap 0
13750         IFS="$OLDIFS"
13751 }
13752
13753 test_130a() {
13754         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13755         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13756
13757         trap cleanup_130 EXIT RETURN
13758
13759         local fm_file=$DIR/$tfile
13760         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13761         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13762                 error "dd failed for $fm_file"
13763
13764         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13765         filefrag -ves $fm_file
13766         RC=$?
13767         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13768                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13769         [ $RC != 0 ] && error "filefrag $fm_file failed"
13770
13771         filefrag_op=$(filefrag -ve -k $fm_file |
13772                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13773         lun=$($LFS getstripe -i $fm_file)
13774
13775         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13776         IFS=$'\n'
13777         tot_len=0
13778         for line in $filefrag_op
13779         do
13780                 frag_lun=`echo $line | cut -d: -f5`
13781                 ext_len=`echo $line | cut -d: -f4`
13782                 if (( $frag_lun != $lun )); then
13783                         cleanup_130
13784                         error "FIEMAP on 1-stripe file($fm_file) failed"
13785                         return
13786                 fi
13787                 (( tot_len += ext_len ))
13788         done
13789
13790         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13791                 cleanup_130
13792                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13793                 return
13794         fi
13795
13796         cleanup_130
13797
13798         echo "FIEMAP on single striped file succeeded"
13799 }
13800 run_test 130a "FIEMAP (1-stripe file)"
13801
13802 test_130b() {
13803         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13804
13805         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13806         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13807
13808         trap cleanup_130 EXIT RETURN
13809
13810         local fm_file=$DIR/$tfile
13811         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13812                         error "setstripe on $fm_file"
13813         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13814                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13815
13816         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13817                 error "dd failed on $fm_file"
13818
13819         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13820         filefrag_op=$(filefrag -ve -k $fm_file |
13821                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13822
13823         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13824                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13825
13826         IFS=$'\n'
13827         tot_len=0
13828         num_luns=1
13829         for line in $filefrag_op
13830         do
13831                 frag_lun=$(echo $line | cut -d: -f5 |
13832                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13833                 ext_len=$(echo $line | cut -d: -f4)
13834                 if (( $frag_lun != $last_lun )); then
13835                         if (( tot_len != 1024 )); then
13836                                 cleanup_130
13837                                 error "FIEMAP on $fm_file failed; returned " \
13838                                 "len $tot_len for OST $last_lun instead of 1024"
13839                                 return
13840                         else
13841                                 (( num_luns += 1 ))
13842                                 tot_len=0
13843                         fi
13844                 fi
13845                 (( tot_len += ext_len ))
13846                 last_lun=$frag_lun
13847         done
13848         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13849                 cleanup_130
13850                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13851                         "luns or wrong len for OST $last_lun"
13852                 return
13853         fi
13854
13855         cleanup_130
13856
13857         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13858 }
13859 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13860
13861 test_130c() {
13862         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13863
13864         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13865         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13866
13867         trap cleanup_130 EXIT RETURN
13868
13869         local fm_file=$DIR/$tfile
13870         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13871         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13872                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13873
13874         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13875                         error "dd failed on $fm_file"
13876
13877         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13878         filefrag_op=$(filefrag -ve -k $fm_file |
13879                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13880
13881         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13882                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13883
13884         IFS=$'\n'
13885         tot_len=0
13886         num_luns=1
13887         for line in $filefrag_op
13888         do
13889                 frag_lun=$(echo $line | cut -d: -f5 |
13890                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13891                 ext_len=$(echo $line | cut -d: -f4)
13892                 if (( $frag_lun != $last_lun )); then
13893                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13894                         if (( logical != 512 )); then
13895                                 cleanup_130
13896                                 error "FIEMAP on $fm_file failed; returned " \
13897                                 "logical start for lun $logical instead of 512"
13898                                 return
13899                         fi
13900                         if (( tot_len != 512 )); then
13901                                 cleanup_130
13902                                 error "FIEMAP on $fm_file failed; returned " \
13903                                 "len $tot_len for OST $last_lun instead of 1024"
13904                                 return
13905                         else
13906                                 (( num_luns += 1 ))
13907                                 tot_len=0
13908                         fi
13909                 fi
13910                 (( tot_len += ext_len ))
13911                 last_lun=$frag_lun
13912         done
13913         if (( num_luns != 2 || tot_len != 512 )); then
13914                 cleanup_130
13915                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13916                         "luns or wrong len for OST $last_lun"
13917                 return
13918         fi
13919
13920         cleanup_130
13921
13922         echo "FIEMAP on 2-stripe file with hole succeeded"
13923 }
13924 run_test 130c "FIEMAP (2-stripe file with hole)"
13925
13926 test_130d() {
13927         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13928
13929         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13930         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13931
13932         trap cleanup_130 EXIT RETURN
13933
13934         local fm_file=$DIR/$tfile
13935         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13936                         error "setstripe on $fm_file"
13937         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13938                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13939
13940         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13941         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13942                 error "dd failed on $fm_file"
13943
13944         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13945         filefrag_op=$(filefrag -ve -k $fm_file |
13946                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13947
13948         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13949                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13950
13951         IFS=$'\n'
13952         tot_len=0
13953         num_luns=1
13954         for line in $filefrag_op
13955         do
13956                 frag_lun=$(echo $line | cut -d: -f5 |
13957                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13958                 ext_len=$(echo $line | cut -d: -f4)
13959                 if (( $frag_lun != $last_lun )); then
13960                         if (( tot_len != 1024 )); then
13961                                 cleanup_130
13962                                 error "FIEMAP on $fm_file failed; returned " \
13963                                 "len $tot_len for OST $last_lun instead of 1024"
13964                                 return
13965                         else
13966                                 (( num_luns += 1 ))
13967                                 tot_len=0
13968                         fi
13969                 fi
13970                 (( tot_len += ext_len ))
13971                 last_lun=$frag_lun
13972         done
13973         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13974                 cleanup_130
13975                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13976                         "luns or wrong len for OST $last_lun"
13977                 return
13978         fi
13979
13980         cleanup_130
13981
13982         echo "FIEMAP on N-stripe file succeeded"
13983 }
13984 run_test 130d "FIEMAP (N-stripe file)"
13985
13986 test_130e() {
13987         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13988
13989         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13990         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13991
13992         trap cleanup_130 EXIT RETURN
13993
13994         local fm_file=$DIR/$tfile
13995         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13996
13997         NUM_BLKS=512
13998         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13999         for ((i = 0; i < $NUM_BLKS; i++)); do
14000                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14001                         conv=notrunc > /dev/null 2>&1
14002         done
14003
14004         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14005         filefrag_op=$(filefrag -ve -k $fm_file |
14006                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14007
14008         last_lun=$(echo $filefrag_op | cut -d: -f5)
14009
14010         IFS=$'\n'
14011         tot_len=0
14012         num_luns=1
14013         for line in $filefrag_op; do
14014                 frag_lun=$(echo $line | cut -d: -f5)
14015                 ext_len=$(echo $line | cut -d: -f4)
14016                 if [[ "$frag_lun" != "$last_lun" ]]; then
14017                         if (( tot_len != $EXPECTED_LEN )); then
14018                                 cleanup_130
14019                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
14020                         else
14021                                 (( num_luns += 1 ))
14022                                 tot_len=0
14023                         fi
14024                 fi
14025                 (( tot_len += ext_len ))
14026                 last_lun=$frag_lun
14027         done
14028         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
14029                 cleanup_130
14030                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
14031         fi
14032
14033         echo "FIEMAP with continuation calls succeeded"
14034 }
14035 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14036
14037 test_130f() {
14038         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14039         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
14040
14041         local fm_file=$DIR/$tfile
14042         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14043                 error "multiop create with lov_delay_create on $fm_file"
14044
14045         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14046         filefrag_extents=$(filefrag -vek $fm_file |
14047                            awk '/extents? found/ { print $2 }')
14048         if [[ "$filefrag_extents" != "0" ]]; then
14049                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14050         fi
14051
14052         rm -f $fm_file
14053 }
14054 run_test 130f "FIEMAP (unstriped file)"
14055
14056 test_130g() {
14057         local file=$DIR/$tfile
14058         local nr=$((OSTCOUNT * 100))
14059
14060         $LFS setstripe -C $nr $file ||
14061                 error "failed to setstripe -C $nr $file"
14062
14063         dd if=/dev/zero of=$file count=$nr bs=1M
14064         sync
14065         nr=$($LFS getstripe -c $file)
14066
14067         local extents=$(filefrag -v $file |
14068                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14069
14070         echo "filefrag list $extents extents in file with stripecount $nr"
14071         if (( extents < nr )); then
14072                 $LFS getstripe $file
14073                 filefrag -v $file
14074                 error "filefrag printed $extents < $nr extents"
14075         fi
14076
14077         rm -f $file
14078 }
14079 run_test 130g "FIEMAP (overstripe file)"
14080
14081 # Test for writev/readv
14082 test_131a() {
14083         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14084                 error "writev test failed"
14085         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14086                 error "readv failed"
14087         rm -f $DIR/$tfile
14088 }
14089 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14090
14091 test_131b() {
14092         local fsize=$((524288 + 1048576 + 1572864))
14093         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14094                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14095                         error "append writev test failed"
14096
14097         ((fsize += 1572864 + 1048576))
14098         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14099                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14100                         error "append writev test failed"
14101         rm -f $DIR/$tfile
14102 }
14103 run_test 131b "test append writev"
14104
14105 test_131c() {
14106         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14107         error "NOT PASS"
14108 }
14109 run_test 131c "test read/write on file w/o objects"
14110
14111 test_131d() {
14112         rwv -f $DIR/$tfile -w -n 1 1572864
14113         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14114         if [ "$NOB" != 1572864 ]; then
14115                 error "Short read filed: read $NOB bytes instead of 1572864"
14116         fi
14117         rm -f $DIR/$tfile
14118 }
14119 run_test 131d "test short read"
14120
14121 test_131e() {
14122         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14123         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14124         error "read hitting hole failed"
14125         rm -f $DIR/$tfile
14126 }
14127 run_test 131e "test read hitting hole"
14128
14129 check_stats() {
14130         local facet=$1
14131         local op=$2
14132         local want=${3:-0}
14133         local res
14134
14135         case $facet in
14136         mds*) res=$(do_facet $facet \
14137                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14138                  ;;
14139         ost*) res=$(do_facet $facet \
14140                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14141                  ;;
14142         *) error "Wrong facet '$facet'" ;;
14143         esac
14144         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14145         # if the argument $3 is zero, it means any stat increment is ok.
14146         if [[ $want -gt 0 ]]; then
14147                 local count=$(echo $res | awk '{ print $2 }')
14148                 [[ $count -ne $want ]] &&
14149                         error "The $op counter on $facet is $count, not $want"
14150         fi
14151 }
14152
14153 test_133a() {
14154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14155         remote_ost_nodsh && skip "remote OST with nodsh"
14156         remote_mds_nodsh && skip "remote MDS with nodsh"
14157         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14158                 skip_env "MDS doesn't support rename stats"
14159
14160         local testdir=$DIR/${tdir}/stats_testdir
14161
14162         mkdir -p $DIR/${tdir}
14163
14164         # clear stats.
14165         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14166         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14167
14168         # verify mdt stats first.
14169         mkdir ${testdir} || error "mkdir failed"
14170         check_stats $SINGLEMDS "mkdir" 1
14171         touch ${testdir}/${tfile} || error "touch failed"
14172         check_stats $SINGLEMDS "open" 1
14173         check_stats $SINGLEMDS "close" 1
14174         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14175                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14176                 check_stats $SINGLEMDS "mknod" 2
14177         }
14178         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14179         check_stats $SINGLEMDS "unlink" 1
14180         rm -f ${testdir}/${tfile} || error "file remove failed"
14181         check_stats $SINGLEMDS "unlink" 2
14182
14183         # remove working dir and check mdt stats again.
14184         rmdir ${testdir} || error "rmdir failed"
14185         check_stats $SINGLEMDS "rmdir" 1
14186
14187         local testdir1=$DIR/${tdir}/stats_testdir1
14188         mkdir -p ${testdir}
14189         mkdir -p ${testdir1}
14190         touch ${testdir1}/test1
14191         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14192         check_stats $SINGLEMDS "crossdir_rename" 1
14193
14194         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14195         check_stats $SINGLEMDS "samedir_rename" 1
14196
14197         rm -rf $DIR/${tdir}
14198 }
14199 run_test 133a "Verifying MDT stats ========================================"
14200
14201 test_133b() {
14202         local res
14203
14204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14205         remote_ost_nodsh && skip "remote OST with nodsh"
14206         remote_mds_nodsh && skip "remote MDS with nodsh"
14207
14208         local testdir=$DIR/${tdir}/stats_testdir
14209
14210         mkdir -p ${testdir} || error "mkdir failed"
14211         touch ${testdir}/${tfile} || error "touch failed"
14212         cancel_lru_locks mdc
14213
14214         # clear stats.
14215         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14216         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14217
14218         # extra mdt stats verification.
14219         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14220         check_stats $SINGLEMDS "setattr" 1
14221         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14222         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14223         then            # LU-1740
14224                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14225                 check_stats $SINGLEMDS "getattr" 1
14226         fi
14227         rm -rf $DIR/${tdir}
14228
14229         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14230         # so the check below is not reliable
14231         [ $MDSCOUNT -eq 1 ] || return 0
14232
14233         # Sleep to avoid a cached response.
14234         #define OBD_STATFS_CACHE_SECONDS 1
14235         sleep 2
14236         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14237         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14238         $LFS df || error "lfs failed"
14239         check_stats $SINGLEMDS "statfs" 1
14240
14241         # check aggregated statfs (LU-10018)
14242         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14243                 return 0
14244         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14245                 return 0
14246         sleep 2
14247         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14248         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14249         df $DIR
14250         check_stats $SINGLEMDS "statfs" 1
14251
14252         # We want to check that the client didn't send OST_STATFS to
14253         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14254         # extra care is needed here.
14255         if remote_mds; then
14256                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14257                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14258
14259                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14260                 [ "$res" ] && error "OST got STATFS"
14261         fi
14262
14263         return 0
14264 }
14265 run_test 133b "Verifying extra MDT stats =================================="
14266
14267 test_133c() {
14268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14269         remote_ost_nodsh && skip "remote OST with nodsh"
14270         remote_mds_nodsh && skip "remote MDS with nodsh"
14271
14272         local testdir=$DIR/$tdir/stats_testdir
14273
14274         test_mkdir -p $testdir
14275
14276         # verify obdfilter stats.
14277         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14278         sync
14279         cancel_lru_locks osc
14280         wait_delete_completed
14281
14282         # clear stats.
14283         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14284         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14285
14286         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14287                 error "dd failed"
14288         sync
14289         cancel_lru_locks osc
14290         check_stats ost1 "write" 1
14291
14292         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14293         check_stats ost1 "read" 1
14294
14295         > $testdir/$tfile || error "truncate failed"
14296         check_stats ost1 "punch" 1
14297
14298         rm -f $testdir/$tfile || error "file remove failed"
14299         wait_delete_completed
14300         check_stats ost1 "destroy" 1
14301
14302         rm -rf $DIR/$tdir
14303 }
14304 run_test 133c "Verifying OST stats ========================================"
14305
14306 order_2() {
14307         local value=$1
14308         local orig=$value
14309         local order=1
14310
14311         while [ $value -ge 2 ]; do
14312                 order=$((order*2))
14313                 value=$((value/2))
14314         done
14315
14316         if [ $orig -gt $order ]; then
14317                 order=$((order*2))
14318         fi
14319         echo $order
14320 }
14321
14322 size_in_KMGT() {
14323     local value=$1
14324     local size=('K' 'M' 'G' 'T');
14325     local i=0
14326     local size_string=$value
14327
14328     while [ $value -ge 1024 ]; do
14329         if [ $i -gt 3 ]; then
14330             #T is the biggest unit we get here, if that is bigger,
14331             #just return XXXT
14332             size_string=${value}T
14333             break
14334         fi
14335         value=$((value >> 10))
14336         if [ $value -lt 1024 ]; then
14337             size_string=${value}${size[$i]}
14338             break
14339         fi
14340         i=$((i + 1))
14341     done
14342
14343     echo $size_string
14344 }
14345
14346 get_rename_size() {
14347         local size=$1
14348         local context=${2:-.}
14349         local sample=$(do_facet $SINGLEMDS $LCTL \
14350                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14351                 grep -A1 $context |
14352                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14353         echo $sample
14354 }
14355
14356 test_133d() {
14357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14358         remote_ost_nodsh && skip "remote OST with nodsh"
14359         remote_mds_nodsh && skip "remote MDS with nodsh"
14360         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14361                 skip_env "MDS doesn't support rename stats"
14362
14363         local testdir1=$DIR/${tdir}/stats_testdir1
14364         local testdir2=$DIR/${tdir}/stats_testdir2
14365         mkdir -p $DIR/${tdir}
14366
14367         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14368
14369         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14370         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14371
14372         createmany -o $testdir1/test 512 || error "createmany failed"
14373
14374         # check samedir rename size
14375         mv ${testdir1}/test0 ${testdir1}/test_0
14376
14377         local testdir1_size=$(ls -l $DIR/${tdir} |
14378                 awk '/stats_testdir1/ {print $5}')
14379         local testdir2_size=$(ls -l $DIR/${tdir} |
14380                 awk '/stats_testdir2/ {print $5}')
14381
14382         testdir1_size=$(order_2 $testdir1_size)
14383         testdir2_size=$(order_2 $testdir2_size)
14384
14385         testdir1_size=$(size_in_KMGT $testdir1_size)
14386         testdir2_size=$(size_in_KMGT $testdir2_size)
14387
14388         echo "source rename dir size: ${testdir1_size}"
14389         echo "target rename dir size: ${testdir2_size}"
14390
14391         local cmd="do_facet $SINGLEMDS $LCTL "
14392         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14393
14394         eval $cmd || error "$cmd failed"
14395         local samedir=$($cmd | grep 'same_dir')
14396         local same_sample=$(get_rename_size $testdir1_size)
14397         [ -z "$samedir" ] && error "samedir_rename_size count error"
14398         [[ $same_sample -eq 1 ]] ||
14399                 error "samedir_rename_size error $same_sample"
14400         echo "Check same dir rename stats success"
14401
14402         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14403
14404         # check crossdir rename size
14405         mv ${testdir1}/test_0 ${testdir2}/test_0
14406
14407         testdir1_size=$(ls -l $DIR/${tdir} |
14408                 awk '/stats_testdir1/ {print $5}')
14409         testdir2_size=$(ls -l $DIR/${tdir} |
14410                 awk '/stats_testdir2/ {print $5}')
14411
14412         testdir1_size=$(order_2 $testdir1_size)
14413         testdir2_size=$(order_2 $testdir2_size)
14414
14415         testdir1_size=$(size_in_KMGT $testdir1_size)
14416         testdir2_size=$(size_in_KMGT $testdir2_size)
14417
14418         echo "source rename dir size: ${testdir1_size}"
14419         echo "target rename dir size: ${testdir2_size}"
14420
14421         eval $cmd || error "$cmd failed"
14422         local crossdir=$($cmd | grep 'crossdir')
14423         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14424         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14425         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14426         [[ $src_sample -eq 1 ]] ||
14427                 error "crossdir_rename_size error $src_sample"
14428         [[ $tgt_sample -eq 1 ]] ||
14429                 error "crossdir_rename_size error $tgt_sample"
14430         echo "Check cross dir rename stats success"
14431         rm -rf $DIR/${tdir}
14432 }
14433 run_test 133d "Verifying rename_stats ========================================"
14434
14435 test_133e() {
14436         remote_mds_nodsh && skip "remote MDS with nodsh"
14437         remote_ost_nodsh && skip "remote OST with nodsh"
14438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14439
14440         local testdir=$DIR/${tdir}/stats_testdir
14441         local ctr f0 f1 bs=32768 count=42 sum
14442
14443         mkdir -p ${testdir} || error "mkdir failed"
14444
14445         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14446
14447         for ctr in {write,read}_bytes; do
14448                 sync
14449                 cancel_lru_locks osc
14450
14451                 do_facet ost1 $LCTL set_param -n \
14452                         "obdfilter.*.exports.clear=clear"
14453
14454                 if [ $ctr = write_bytes ]; then
14455                         f0=/dev/zero
14456                         f1=${testdir}/${tfile}
14457                 else
14458                         f0=${testdir}/${tfile}
14459                         f1=/dev/null
14460                 fi
14461
14462                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14463                         error "dd failed"
14464                 sync
14465                 cancel_lru_locks osc
14466
14467                 sum=$(do_facet ost1 $LCTL get_param \
14468                         "obdfilter.*.exports.*.stats" |
14469                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14470                                 $1 == ctr { sum += $7 }
14471                                 END { printf("%0.0f", sum) }')
14472
14473                 if ((sum != bs * count)); then
14474                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14475                 fi
14476         done
14477
14478         rm -rf $DIR/${tdir}
14479 }
14480 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14481
14482 test_133f() {
14483         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14484                 skip "too old lustre for get_param -R ($facet_ver)"
14485
14486         # verifying readability.
14487         $LCTL get_param -R '*' &> /dev/null
14488
14489         # Verifing writability with badarea_io.
14490         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14491         local skipped_params='force_lbug|changelog_mask|daemon_file'
14492         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14493                 egrep -v "$skipped_params" |
14494                 xargs -n 1 find $proc_dirs -name |
14495                 xargs -n 1 badarea_io ||
14496                 error "client badarea_io failed"
14497
14498         # remount the FS in case writes/reads /proc break the FS
14499         cleanup || error "failed to unmount"
14500         setup || error "failed to setup"
14501 }
14502 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14503
14504 test_133g() {
14505         remote_mds_nodsh && skip "remote MDS with nodsh"
14506         remote_ost_nodsh && skip "remote OST with nodsh"
14507
14508         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14509         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14510         local facet
14511         for facet in mds1 ost1; do
14512                 local facet_ver=$(lustre_version_code $facet)
14513                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14514                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14515                 else
14516                         log "$facet: too old lustre for get_param -R"
14517                 fi
14518                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14519                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14520                                 tr -d = | egrep -v $skipped_params |
14521                                 xargs -n 1 find $proc_dirs -name |
14522                                 xargs -n 1 badarea_io" ||
14523                                         error "$facet badarea_io failed"
14524                 else
14525                         skip_noexit "$facet: too old lustre for get_param -R"
14526                 fi
14527         done
14528
14529         # remount the FS in case writes/reads /proc break the FS
14530         cleanup || error "failed to unmount"
14531         setup || error "failed to setup"
14532 }
14533 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14534
14535 test_133h() {
14536         remote_mds_nodsh && skip "remote MDS with nodsh"
14537         remote_ost_nodsh && skip "remote OST with nodsh"
14538         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14539                 skip "Need MDS version at least 2.9.54"
14540
14541         local facet
14542         for facet in client mds1 ost1; do
14543                 # Get the list of files that are missing the terminating newline
14544                 local plist=$(do_facet $facet
14545                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14546                 local ent
14547                 for ent in $plist; do
14548                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14549                                 awk -v FS='\v' -v RS='\v\v' \
14550                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14551                                         print FILENAME}'" 2>/dev/null)
14552                         [ -z $missing ] || {
14553                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14554                                 error "file does not end with newline: $facet-$ent"
14555                         }
14556                 done
14557         done
14558 }
14559 run_test 133h "Proc files should end with newlines"
14560
14561 test_134a() {
14562         remote_mds_nodsh && skip "remote MDS with nodsh"
14563         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14564                 skip "Need MDS version at least 2.7.54"
14565
14566         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14567         cancel_lru_locks mdc
14568
14569         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14570         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14571         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14572
14573         local nr=1000
14574         createmany -o $DIR/$tdir/f $nr ||
14575                 error "failed to create $nr files in $DIR/$tdir"
14576         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14577
14578         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14579         do_facet mds1 $LCTL set_param fail_loc=0x327
14580         do_facet mds1 $LCTL set_param fail_val=500
14581         touch $DIR/$tdir/m
14582
14583         echo "sleep 10 seconds ..."
14584         sleep 10
14585         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14586
14587         do_facet mds1 $LCTL set_param fail_loc=0
14588         do_facet mds1 $LCTL set_param fail_val=0
14589         [ $lck_cnt -lt $unused ] ||
14590                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14591
14592         rm $DIR/$tdir/m
14593         unlinkmany $DIR/$tdir/f $nr
14594 }
14595 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14596
14597 test_134b() {
14598         remote_mds_nodsh && skip "remote MDS with nodsh"
14599         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14600                 skip "Need MDS version at least 2.7.54"
14601
14602         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14603         cancel_lru_locks mdc
14604
14605         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14606                         ldlm.lock_reclaim_threshold_mb)
14607         # disable reclaim temporarily
14608         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14609
14610         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14611         do_facet mds1 $LCTL set_param fail_loc=0x328
14612         do_facet mds1 $LCTL set_param fail_val=500
14613
14614         $LCTL set_param debug=+trace
14615
14616         local nr=600
14617         createmany -o $DIR/$tdir/f $nr &
14618         local create_pid=$!
14619
14620         echo "Sleep $TIMEOUT seconds ..."
14621         sleep $TIMEOUT
14622         if ! ps -p $create_pid  > /dev/null 2>&1; then
14623                 do_facet mds1 $LCTL set_param fail_loc=0
14624                 do_facet mds1 $LCTL set_param fail_val=0
14625                 do_facet mds1 $LCTL set_param \
14626                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14627                 error "createmany finished incorrectly!"
14628         fi
14629         do_facet mds1 $LCTL set_param fail_loc=0
14630         do_facet mds1 $LCTL set_param fail_val=0
14631         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14632         wait $create_pid || return 1
14633
14634         unlinkmany $DIR/$tdir/f $nr
14635 }
14636 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14637
14638 test_135() {
14639         remote_mds_nodsh && skip "remote MDS with nodsh"
14640         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14641                 skip "Need MDS version at least 2.13.50"
14642         local fname
14643
14644         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14645
14646 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14647         #set only one record at plain llog
14648         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14649
14650         #fill already existed plain llog each 64767
14651         #wrapping whole catalog
14652         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14653
14654         createmany -o $DIR/$tdir/$tfile_ 64700
14655         for (( i = 0; i < 64700; i = i + 2 ))
14656         do
14657                 rm $DIR/$tdir/$tfile_$i &
14658                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14659                 local pid=$!
14660                 wait $pid
14661         done
14662
14663         #waiting osp synchronization
14664         wait_delete_completed
14665 }
14666 run_test 135 "Race catalog processing"
14667
14668 test_136() {
14669         remote_mds_nodsh && skip "remote MDS with nodsh"
14670         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14671                 skip "Need MDS version at least 2.13.50"
14672         local fname
14673
14674         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14675         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14676         #set only one record at plain llog
14677 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14678         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14679
14680         #fill already existed 2 plain llogs each 64767
14681         #wrapping whole catalog
14682         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14683         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14684         wait_delete_completed
14685
14686         createmany -o $DIR/$tdir/$tfile_ 10
14687         sleep 25
14688
14689         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14690         for (( i = 0; i < 10; i = i + 3 ))
14691         do
14692                 rm $DIR/$tdir/$tfile_$i &
14693                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14694                 local pid=$!
14695                 wait $pid
14696                 sleep 7
14697                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14698         done
14699
14700         #waiting osp synchronization
14701         wait_delete_completed
14702 }
14703 run_test 136 "Race catalog processing 2"
14704
14705 test_140() { #bug-17379
14706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14707
14708         test_mkdir $DIR/$tdir
14709         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14710         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14711
14712         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14713         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14714         local i=0
14715         while i=$((i + 1)); do
14716                 test_mkdir $i
14717                 cd $i || error "Changing to $i"
14718                 ln -s ../stat stat || error "Creating stat symlink"
14719                 # Read the symlink until ELOOP present,
14720                 # not LBUGing the system is considered success,
14721                 # we didn't overrun the stack.
14722                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14723                 if [ $ret -ne 0 ]; then
14724                         if [ $ret -eq 40 ]; then
14725                                 break  # -ELOOP
14726                         else
14727                                 error "Open stat symlink"
14728                                         return
14729                         fi
14730                 fi
14731         done
14732         i=$((i - 1))
14733         echo "The symlink depth = $i"
14734         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14735                 error "Invalid symlink depth"
14736
14737         # Test recursive symlink
14738         ln -s symlink_self symlink_self
14739         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14740         echo "open symlink_self returns $ret"
14741         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14742 }
14743 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14744
14745 test_150a() {
14746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14747
14748         local TF="$TMP/$tfile"
14749
14750         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14751         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14752         cp $TF $DIR/$tfile
14753         cancel_lru_locks $OSC
14754         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14755         remount_client $MOUNT
14756         df -P $MOUNT
14757         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14758
14759         $TRUNCATE $TF 6000
14760         $TRUNCATE $DIR/$tfile 6000
14761         cancel_lru_locks $OSC
14762         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14763
14764         echo "12345" >>$TF
14765         echo "12345" >>$DIR/$tfile
14766         cancel_lru_locks $OSC
14767         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14768
14769         echo "12345" >>$TF
14770         echo "12345" >>$DIR/$tfile
14771         cancel_lru_locks $OSC
14772         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14773 }
14774 run_test 150a "truncate/append tests"
14775
14776 test_150b() {
14777         check_set_fallocate_or_skip
14778
14779         touch $DIR/$tfile
14780         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14781         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14782 }
14783 run_test 150b "Verify fallocate (prealloc) functionality"
14784
14785 test_150bb() {
14786         check_set_fallocate_or_skip
14787
14788         touch $DIR/$tfile
14789         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14790         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14791         > $DIR/$tfile
14792         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14793         # precomputed md5sum for 20MB of zeroes
14794         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14795         local sum=($(md5sum $DIR/$tfile))
14796
14797         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14798
14799         check_set_fallocate 1
14800
14801         > $DIR/$tfile
14802         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14803         sum=($(md5sum $DIR/$tfile))
14804
14805         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14806 }
14807 run_test 150bb "Verify fallocate modes both zero space"
14808
14809 test_150c() {
14810         check_set_fallocate_or_skip
14811         local striping="-c2"
14812
14813         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14814         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14815         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14816         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14817         local want=$((OSTCOUNT * 1048576))
14818
14819         # Must allocate all requested space, not more than 5% extra
14820         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14821                 error "bytes $bytes is not $want"
14822
14823         rm -f $DIR/$tfile
14824
14825         echo "verify fallocate on PFL file"
14826
14827         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14828
14829         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14830                 error "Create $DIR/$tfile failed"
14831         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14832         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14833         want=$((512 * 1048576))
14834
14835         # Must allocate all requested space, not more than 5% extra
14836         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14837                 error "bytes $bytes is not $want"
14838 }
14839 run_test 150c "Verify fallocate Size and Blocks"
14840
14841 test_150d() {
14842         check_set_fallocate_or_skip
14843         local striping="-c2"
14844
14845         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14846
14847         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14848         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14849                 error "setstripe failed"
14850         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14851         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14852         local want=$((OSTCOUNT * 1048576))
14853
14854         # Must allocate all requested space, not more than 5% extra
14855         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14856                 error "bytes $bytes is not $want"
14857 }
14858 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14859
14860 test_150e() {
14861         check_set_fallocate_or_skip
14862
14863         echo "df before:"
14864         $LFS df
14865         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14866         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14867                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14868
14869         # Find OST with Minimum Size
14870         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14871                        sort -un | head -1)
14872
14873         # Get 100MB per OST of the available space to reduce run time
14874         # else 60% of the available space if we are running SLOW tests
14875         if [ $SLOW == "no" ]; then
14876                 local space=$((1024 * 100 * OSTCOUNT))
14877         else
14878                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14879         fi
14880
14881         fallocate -l${space}k $DIR/$tfile ||
14882                 error "fallocate ${space}k $DIR/$tfile failed"
14883         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14884
14885         # get size immediately after fallocate. This should be correctly
14886         # updated
14887         local size=$(stat -c '%s' $DIR/$tfile)
14888         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14889
14890         # Sleep for a while for statfs to get updated. And not pull from cache.
14891         sleep 2
14892
14893         echo "df after fallocate:"
14894         $LFS df
14895
14896         (( size / 1024 == space )) || error "size $size != requested $space"
14897         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14898                 error "used $used < space $space"
14899
14900         rm $DIR/$tfile || error "rm failed"
14901         sync
14902         wait_delete_completed
14903
14904         echo "df after unlink:"
14905         $LFS df
14906 }
14907 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14908
14909 test_150f() {
14910         local size
14911         local blocks
14912         local want_size_before=20480 # in bytes
14913         local want_blocks_before=40 # 512 sized blocks
14914         local want_blocks_after=24  # 512 sized blocks
14915         local length=$(((want_blocks_before - want_blocks_after) * 512))
14916
14917         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14918                 skip "need at least 2.14.0 for fallocate punch"
14919
14920         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14921                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14922         fi
14923
14924         check_set_fallocate_or_skip
14925         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14926
14927         [[ "x$DOM" == "xyes" ]] &&
14928                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14929
14930         echo "Verify fallocate punch: Range within the file range"
14931         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14932                 error "dd failed for bs 4096 and count 5"
14933
14934         # Call fallocate with punch range which is within the file range
14935         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14936                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14937         # client must see changes immediately after fallocate
14938         size=$(stat -c '%s' $DIR/$tfile)
14939         blocks=$(stat -c '%b' $DIR/$tfile)
14940
14941         # Verify punch worked.
14942         (( blocks == want_blocks_after )) ||
14943                 error "punch failed: blocks $blocks != $want_blocks_after"
14944
14945         (( size == want_size_before )) ||
14946                 error "punch failed: size $size != $want_size_before"
14947
14948         # Verify there is hole in file
14949         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14950         # precomputed md5sum
14951         local expect="4a9a834a2db02452929c0a348273b4aa"
14952
14953         cksum=($(md5sum $DIR/$tfile))
14954         [[ "${cksum[0]}" == "$expect" ]] ||
14955                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14956
14957         # Start second sub-case for fallocate punch.
14958         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14959         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14960                 error "dd failed for bs 4096 and count 5"
14961
14962         # Punch range less than block size will have no change in block count
14963         want_blocks_after=40  # 512 sized blocks
14964
14965         # Punch overlaps two blocks and less than blocksize
14966         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14967                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14968         size=$(stat -c '%s' $DIR/$tfile)
14969         blocks=$(stat -c '%b' $DIR/$tfile)
14970
14971         # Verify punch worked.
14972         (( blocks == want_blocks_after )) ||
14973                 error "punch failed: blocks $blocks != $want_blocks_after"
14974
14975         (( size == want_size_before )) ||
14976                 error "punch failed: size $size != $want_size_before"
14977
14978         # Verify if range is really zero'ed out. We expect Zeros.
14979         # precomputed md5sum
14980         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14981         cksum=($(md5sum $DIR/$tfile))
14982         [[ "${cksum[0]}" == "$expect" ]] ||
14983                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14984 }
14985 run_test 150f "Verify fallocate punch functionality"
14986
14987 test_150g() {
14988         local space
14989         local size
14990         local blocks
14991         local blocks_after
14992         local size_after
14993         local BS=4096 # Block size in bytes
14994
14995         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14996                 skip "need at least 2.14.0 for fallocate punch"
14997
14998         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14999                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15000         fi
15001
15002         check_set_fallocate_or_skip
15003         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15004
15005         if [[ "x$DOM" == "xyes" ]]; then
15006                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15007                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15008         else
15009                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15010                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15011         fi
15012
15013         # Get 100MB per OST of the available space to reduce run time
15014         # else 60% of the available space if we are running SLOW tests
15015         if [ $SLOW == "no" ]; then
15016                 space=$((1024 * 100 * OSTCOUNT))
15017         else
15018                 # Find OST with Minimum Size
15019                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15020                         sort -un | head -1)
15021                 echo "min size OST: $space"
15022                 space=$(((space * 60)/100 * OSTCOUNT))
15023         fi
15024         # space in 1k units, round to 4k blocks
15025         local blkcount=$((space * 1024 / $BS))
15026
15027         echo "Verify fallocate punch: Very large Range"
15028         fallocate -l${space}k $DIR/$tfile ||
15029                 error "fallocate ${space}k $DIR/$tfile failed"
15030         # write 1M at the end, start and in the middle
15031         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15032                 error "dd failed: bs $BS count 256"
15033         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15034                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15035         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15036                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15037
15038         # Gather stats.
15039         size=$(stat -c '%s' $DIR/$tfile)
15040
15041         # gather punch length.
15042         local punch_size=$((size - (BS * 2)))
15043
15044         echo "punch_size = $punch_size"
15045         echo "size - punch_size: $((size - punch_size))"
15046         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15047
15048         # Call fallocate to punch all except 2 blocks. We leave the
15049         # first and the last block
15050         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15051         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15052                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15053
15054         size_after=$(stat -c '%s' $DIR/$tfile)
15055         blocks_after=$(stat -c '%b' $DIR/$tfile)
15056
15057         # Verify punch worked.
15058         # Size should be kept
15059         (( size == size_after )) ||
15060                 error "punch failed: size $size != $size_after"
15061
15062         # two 4k data blocks to remain plus possible 1 extra extent block
15063         (( blocks_after <= ((BS / 512) * 3) )) ||
15064                 error "too many blocks remains: $blocks_after"
15065
15066         # Verify that file has hole between the first and the last blocks
15067         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15068         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15069
15070         echo "Hole at [$hole_start, $hole_end)"
15071         (( hole_start == BS )) ||
15072                 error "no hole at offset $BS after punch"
15073
15074         (( hole_end == BS + punch_size )) ||
15075                 error "data at offset $hole_end < $((BS + punch_size))"
15076 }
15077 run_test 150g "Verify fallocate punch on large range"
15078
15079 #LU-2902 roc_hit was not able to read all values from lproc
15080 function roc_hit_init() {
15081         local list=$(comma_list $(osts_nodes))
15082         local dir=$DIR/$tdir-check
15083         local file=$dir/$tfile
15084         local BEFORE
15085         local AFTER
15086         local idx
15087
15088         test_mkdir $dir
15089         #use setstripe to do a write to every ost
15090         for i in $(seq 0 $((OSTCOUNT-1))); do
15091                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15092                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15093                 idx=$(printf %04x $i)
15094                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15095                         awk '$1 == "cache_access" {sum += $7}
15096                                 END { printf("%0.0f", sum) }')
15097
15098                 cancel_lru_locks osc
15099                 cat $file >/dev/null
15100
15101                 AFTER=$(get_osd_param $list *OST*$idx stats |
15102                         awk '$1 == "cache_access" {sum += $7}
15103                                 END { printf("%0.0f", sum) }')
15104
15105                 echo BEFORE:$BEFORE AFTER:$AFTER
15106                 if ! let "AFTER - BEFORE == 4"; then
15107                         rm -rf $dir
15108                         error "roc_hit is not safe to use"
15109                 fi
15110                 rm $file
15111         done
15112
15113         rm -rf $dir
15114 }
15115
15116 function roc_hit() {
15117         local list=$(comma_list $(osts_nodes))
15118         echo $(get_osd_param $list '' stats |
15119                 awk '$1 == "cache_hit" {sum += $7}
15120                         END { printf("%0.0f", sum) }')
15121 }
15122
15123 function set_cache() {
15124         local on=1
15125
15126         if [ "$2" == "off" ]; then
15127                 on=0;
15128         fi
15129         local list=$(comma_list $(osts_nodes))
15130         set_osd_param $list '' $1_cache_enable $on
15131
15132         cancel_lru_locks osc
15133 }
15134
15135 test_151() {
15136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15137         remote_ost_nodsh && skip "remote OST with nodsh"
15138
15139         local CPAGES=3
15140         local list=$(comma_list $(osts_nodes))
15141
15142         # check whether obdfilter is cache capable at all
15143         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15144                 skip "not cache-capable obdfilter"
15145         fi
15146
15147         # check cache is enabled on all obdfilters
15148         if get_osd_param $list '' read_cache_enable | grep 0; then
15149                 skip "oss cache is disabled"
15150         fi
15151
15152         set_osd_param $list '' writethrough_cache_enable 1
15153
15154         # check write cache is enabled on all obdfilters
15155         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15156                 skip "oss write cache is NOT enabled"
15157         fi
15158
15159         roc_hit_init
15160
15161         #define OBD_FAIL_OBD_NO_LRU  0x609
15162         do_nodes $list $LCTL set_param fail_loc=0x609
15163
15164         # pages should be in the case right after write
15165         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15166                 error "dd failed"
15167
15168         local BEFORE=$(roc_hit)
15169         cancel_lru_locks osc
15170         cat $DIR/$tfile >/dev/null
15171         local AFTER=$(roc_hit)
15172
15173         do_nodes $list $LCTL set_param fail_loc=0
15174
15175         if ! let "AFTER - BEFORE == CPAGES"; then
15176                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15177         fi
15178
15179         cancel_lru_locks osc
15180         # invalidates OST cache
15181         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15182         set_osd_param $list '' read_cache_enable 0
15183         cat $DIR/$tfile >/dev/null
15184
15185         # now data shouldn't be found in the cache
15186         BEFORE=$(roc_hit)
15187         cancel_lru_locks osc
15188         cat $DIR/$tfile >/dev/null
15189         AFTER=$(roc_hit)
15190         if let "AFTER - BEFORE != 0"; then
15191                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15192         fi
15193
15194         set_osd_param $list '' read_cache_enable 1
15195         rm -f $DIR/$tfile
15196 }
15197 run_test 151 "test cache on oss and controls ==============================="
15198
15199 test_152() {
15200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15201
15202         local TF="$TMP/$tfile"
15203
15204         # simulate ENOMEM during write
15205 #define OBD_FAIL_OST_NOMEM      0x226
15206         lctl set_param fail_loc=0x80000226
15207         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15208         cp $TF $DIR/$tfile
15209         sync || error "sync failed"
15210         lctl set_param fail_loc=0
15211
15212         # discard client's cache
15213         cancel_lru_locks osc
15214
15215         # simulate ENOMEM during read
15216         lctl set_param fail_loc=0x80000226
15217         cmp $TF $DIR/$tfile || error "cmp failed"
15218         lctl set_param fail_loc=0
15219
15220         rm -f $TF
15221 }
15222 run_test 152 "test read/write with enomem ============================"
15223
15224 test_153() {
15225         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15226 }
15227 run_test 153 "test if fdatasync does not crash ======================="
15228
15229 dot_lustre_fid_permission_check() {
15230         local fid=$1
15231         local ffid=$MOUNT/.lustre/fid/$fid
15232         local test_dir=$2
15233
15234         echo "stat fid $fid"
15235         stat $ffid > /dev/null || error "stat $ffid failed."
15236         echo "touch fid $fid"
15237         touch $ffid || error "touch $ffid failed."
15238         echo "write to fid $fid"
15239         cat /etc/hosts > $ffid || error "write $ffid failed."
15240         echo "read fid $fid"
15241         diff /etc/hosts $ffid || error "read $ffid failed."
15242         echo "append write to fid $fid"
15243         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15244         echo "rename fid $fid"
15245         mv $ffid $test_dir/$tfile.1 &&
15246                 error "rename $ffid to $tfile.1 should fail."
15247         touch $test_dir/$tfile.1
15248         mv $test_dir/$tfile.1 $ffid &&
15249                 error "rename $tfile.1 to $ffid should fail."
15250         rm -f $test_dir/$tfile.1
15251         echo "truncate fid $fid"
15252         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15253         echo "link fid $fid"
15254         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15255         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15256                 echo "setfacl fid $fid"
15257                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15258                 echo "getfacl fid $fid"
15259                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15260         fi
15261         echo "unlink fid $fid"
15262         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15263         echo "mknod fid $fid"
15264         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15265
15266         fid=[0xf00000400:0x1:0x0]
15267         ffid=$MOUNT/.lustre/fid/$fid
15268
15269         echo "stat non-exist fid $fid"
15270         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15271         echo "write to non-exist fid $fid"
15272         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15273         echo "link new fid $fid"
15274         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15275
15276         mkdir -p $test_dir/$tdir
15277         touch $test_dir/$tdir/$tfile
15278         fid=$($LFS path2fid $test_dir/$tdir)
15279         rc=$?
15280         [ $rc -ne 0 ] &&
15281                 error "error: could not get fid for $test_dir/$dir/$tfile."
15282
15283         ffid=$MOUNT/.lustre/fid/$fid
15284
15285         echo "ls $fid"
15286         ls $ffid > /dev/null || error "ls $ffid failed."
15287         echo "touch $fid/$tfile.1"
15288         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15289
15290         echo "touch $MOUNT/.lustre/fid/$tfile"
15291         touch $MOUNT/.lustre/fid/$tfile && \
15292                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15293
15294         echo "setxattr to $MOUNT/.lustre/fid"
15295         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15296
15297         echo "listxattr for $MOUNT/.lustre/fid"
15298         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15299
15300         echo "delxattr from $MOUNT/.lustre/fid"
15301         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15302
15303         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15304         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15305                 error "touch invalid fid should fail."
15306
15307         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15308         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15309                 error "touch non-normal fid should fail."
15310
15311         echo "rename $tdir to $MOUNT/.lustre/fid"
15312         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15313                 error "rename to $MOUNT/.lustre/fid should fail."
15314
15315         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15316         then            # LU-3547
15317                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15318                 local new_obf_mode=777
15319
15320                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15321                 chmod $new_obf_mode $DIR/.lustre/fid ||
15322                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15323
15324                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15325                 [ $obf_mode -eq $new_obf_mode ] ||
15326                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15327
15328                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15329                 chmod $old_obf_mode $DIR/.lustre/fid ||
15330                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15331         fi
15332
15333         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15334         fid=$($LFS path2fid $test_dir/$tfile-2)
15335
15336         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15337         then # LU-5424
15338                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15339                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15340                         error "create lov data thru .lustre failed"
15341         fi
15342         echo "cp /etc/passwd $test_dir/$tfile-2"
15343         cp /etc/passwd $test_dir/$tfile-2 ||
15344                 error "copy to $test_dir/$tfile-2 failed."
15345         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15346         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15347                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15348
15349         rm -rf $test_dir/tfile.lnk
15350         rm -rf $test_dir/$tfile-2
15351 }
15352
15353 test_154A() {
15354         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15355                 skip "Need MDS version at least 2.4.1"
15356
15357         local tf=$DIR/$tfile
15358         touch $tf
15359
15360         local fid=$($LFS path2fid $tf)
15361         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15362
15363         # check that we get the same pathname back
15364         local rootpath
15365         local found
15366         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15367                 echo "$rootpath $fid"
15368                 found=$($LFS fid2path $rootpath "$fid")
15369                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15370                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15371         done
15372
15373         # check wrong root path format
15374         rootpath=$MOUNT"_wrong"
15375         found=$($LFS fid2path $rootpath "$fid")
15376         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15377 }
15378 run_test 154A "lfs path2fid and fid2path basic checks"
15379
15380 test_154B() {
15381         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15382                 skip "Need MDS version at least 2.4.1"
15383
15384         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15385         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15386         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15387         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15388
15389         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15390         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15391
15392         # check that we get the same pathname
15393         echo "PFID: $PFID, name: $name"
15394         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15395         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15396         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15397                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15398
15399         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15400 }
15401 run_test 154B "verify the ll_decode_linkea tool"
15402
15403 test_154a() {
15404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15405         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15406         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15407                 skip "Need MDS version at least 2.2.51"
15408         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15409
15410         cp /etc/hosts $DIR/$tfile
15411
15412         fid=$($LFS path2fid $DIR/$tfile)
15413         rc=$?
15414         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15415
15416         dot_lustre_fid_permission_check "$fid" $DIR ||
15417                 error "dot lustre permission check $fid failed"
15418
15419         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15420
15421         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15422
15423         touch $MOUNT/.lustre/file &&
15424                 error "creation is not allowed under .lustre"
15425
15426         mkdir $MOUNT/.lustre/dir &&
15427                 error "mkdir is not allowed under .lustre"
15428
15429         rm -rf $DIR/$tfile
15430 }
15431 run_test 154a "Open-by-FID"
15432
15433 test_154b() {
15434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15435         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15437         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15438                 skip "Need MDS version at least 2.2.51"
15439
15440         local remote_dir=$DIR/$tdir/remote_dir
15441         local MDTIDX=1
15442         local rc=0
15443
15444         mkdir -p $DIR/$tdir
15445         $LFS mkdir -i $MDTIDX $remote_dir ||
15446                 error "create remote directory failed"
15447
15448         cp /etc/hosts $remote_dir/$tfile
15449
15450         fid=$($LFS path2fid $remote_dir/$tfile)
15451         rc=$?
15452         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15453
15454         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15455                 error "dot lustre permission check $fid failed"
15456         rm -rf $DIR/$tdir
15457 }
15458 run_test 154b "Open-by-FID for remote directory"
15459
15460 test_154c() {
15461         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15462                 skip "Need MDS version at least 2.4.1"
15463
15464         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15465         local FID1=$($LFS path2fid $DIR/$tfile.1)
15466         local FID2=$($LFS path2fid $DIR/$tfile.2)
15467         local FID3=$($LFS path2fid $DIR/$tfile.3)
15468
15469         local N=1
15470         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15471                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15472                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15473                 local want=FID$N
15474                 [ "$FID" = "${!want}" ] ||
15475                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15476                 N=$((N + 1))
15477         done
15478
15479         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15480         do
15481                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15482                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15483                 N=$((N + 1))
15484         done
15485 }
15486 run_test 154c "lfs path2fid and fid2path multiple arguments"
15487
15488 test_154d() {
15489         remote_mds_nodsh && skip "remote MDS with nodsh"
15490         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15491                 skip "Need MDS version at least 2.5.53"
15492
15493         if remote_mds; then
15494                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15495         else
15496                 nid="0@lo"
15497         fi
15498         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15499         local fd
15500         local cmd
15501
15502         rm -f $DIR/$tfile
15503         touch $DIR/$tfile
15504
15505         local fid=$($LFS path2fid $DIR/$tfile)
15506         # Open the file
15507         fd=$(free_fd)
15508         cmd="exec $fd<$DIR/$tfile"
15509         eval $cmd
15510         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15511         echo "$fid_list" | grep "$fid"
15512         rc=$?
15513
15514         cmd="exec $fd>/dev/null"
15515         eval $cmd
15516         if [ $rc -ne 0 ]; then
15517                 error "FID $fid not found in open files list $fid_list"
15518         fi
15519 }
15520 run_test 154d "Verify open file fid"
15521
15522 test_154e()
15523 {
15524         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15525                 skip "Need MDS version at least 2.6.50"
15526
15527         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15528                 error ".lustre returned by readdir"
15529         fi
15530 }
15531 run_test 154e ".lustre is not returned by readdir"
15532
15533 test_154f() {
15534         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15535
15536         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15537         mkdir_on_mdt0 $DIR/$tdir
15538         # test dirs inherit from its stripe
15539         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15540         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15541         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15542         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15543         touch $DIR/f
15544
15545         # get fid of parents
15546         local FID0=$($LFS path2fid $DIR/$tdir)
15547         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15548         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15549         local FID3=$($LFS path2fid $DIR)
15550
15551         # check that path2fid --parents returns expected <parent_fid>/name
15552         # 1) test for a directory (single parent)
15553         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15554         [ "$parent" == "$FID0/foo1" ] ||
15555                 error "expected parent: $FID0/foo1, got: $parent"
15556
15557         # 2) test for a file with nlink > 1 (multiple parents)
15558         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15559         echo "$parent" | grep -F "$FID1/$tfile" ||
15560                 error "$FID1/$tfile not returned in parent list"
15561         echo "$parent" | grep -F "$FID2/link" ||
15562                 error "$FID2/link not returned in parent list"
15563
15564         # 3) get parent by fid
15565         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15566         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15567         echo "$parent" | grep -F "$FID1/$tfile" ||
15568                 error "$FID1/$tfile not returned in parent list (by fid)"
15569         echo "$parent" | grep -F "$FID2/link" ||
15570                 error "$FID2/link not returned in parent list (by fid)"
15571
15572         # 4) test for entry in root directory
15573         parent=$($LFS path2fid --parents $DIR/f)
15574         echo "$parent" | grep -F "$FID3/f" ||
15575                 error "$FID3/f not returned in parent list"
15576
15577         # 5) test it on root directory
15578         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15579                 error "$MOUNT should not have parents"
15580
15581         # enable xattr caching and check that linkea is correctly updated
15582         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15583         save_lustre_params client "llite.*.xattr_cache" > $save
15584         lctl set_param llite.*.xattr_cache 1
15585
15586         # 6.1) linkea update on rename
15587         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15588
15589         # get parents by fid
15590         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15591         # foo1 should no longer be returned in parent list
15592         echo "$parent" | grep -F "$FID1" &&
15593                 error "$FID1 should no longer be in parent list"
15594         # the new path should appear
15595         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15596                 error "$FID2/$tfile.moved is not in parent list"
15597
15598         # 6.2) linkea update on unlink
15599         rm -f $DIR/$tdir/foo2/link
15600         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15601         # foo2/link should no longer be returned in parent list
15602         echo "$parent" | grep -F "$FID2/link" &&
15603                 error "$FID2/link should no longer be in parent list"
15604         true
15605
15606         rm -f $DIR/f
15607         restore_lustre_params < $save
15608         rm -f $save
15609 }
15610 run_test 154f "get parent fids by reading link ea"
15611
15612 test_154g()
15613 {
15614         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15615         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15616            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15617                 skip "Need MDS version at least 2.6.92"
15618
15619         mkdir_on_mdt0 $DIR/$tdir
15620         llapi_fid_test -d $DIR/$tdir
15621 }
15622 run_test 154g "various llapi FID tests"
15623
15624 test_155_small_load() {
15625     local temp=$TMP/$tfile
15626     local file=$DIR/$tfile
15627
15628     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15629         error "dd of=$temp bs=6096 count=1 failed"
15630     cp $temp $file
15631     cancel_lru_locks $OSC
15632     cmp $temp $file || error "$temp $file differ"
15633
15634     $TRUNCATE $temp 6000
15635     $TRUNCATE $file 6000
15636     cmp $temp $file || error "$temp $file differ (truncate1)"
15637
15638     echo "12345" >>$temp
15639     echo "12345" >>$file
15640     cmp $temp $file || error "$temp $file differ (append1)"
15641
15642     echo "12345" >>$temp
15643     echo "12345" >>$file
15644     cmp $temp $file || error "$temp $file differ (append2)"
15645
15646     rm -f $temp $file
15647     true
15648 }
15649
15650 test_155_big_load() {
15651         remote_ost_nodsh && skip "remote OST with nodsh"
15652
15653         local temp=$TMP/$tfile
15654         local file=$DIR/$tfile
15655
15656         free_min_max
15657         local cache_size=$(do_facet ost$((MAXI+1)) \
15658                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15659         local large_file_size=$((cache_size * 2))
15660
15661         echo "OSS cache size: $cache_size KB"
15662         echo "Large file size: $large_file_size KB"
15663
15664         [ $MAXV -le $large_file_size ] &&
15665                 skip_env "max available OST size needs > $large_file_size KB"
15666
15667         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15668
15669         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15670                 error "dd of=$temp bs=$large_file_size count=1k failed"
15671         cp $temp $file
15672         ls -lh $temp $file
15673         cancel_lru_locks osc
15674         cmp $temp $file || error "$temp $file differ"
15675
15676         rm -f $temp $file
15677         true
15678 }
15679
15680 save_writethrough() {
15681         local facets=$(get_facets OST)
15682
15683         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15684 }
15685
15686 test_155a() {
15687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15688
15689         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15690
15691         save_writethrough $p
15692
15693         set_cache read on
15694         set_cache writethrough on
15695         test_155_small_load
15696         restore_lustre_params < $p
15697         rm -f $p
15698 }
15699 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15700
15701 test_155b() {
15702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15703
15704         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15705
15706         save_writethrough $p
15707
15708         set_cache read on
15709         set_cache writethrough off
15710         test_155_small_load
15711         restore_lustre_params < $p
15712         rm -f $p
15713 }
15714 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15715
15716 test_155c() {
15717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15718
15719         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15720
15721         save_writethrough $p
15722
15723         set_cache read off
15724         set_cache writethrough on
15725         test_155_small_load
15726         restore_lustre_params < $p
15727         rm -f $p
15728 }
15729 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15730
15731 test_155d() {
15732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15733
15734         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15735
15736         save_writethrough $p
15737
15738         set_cache read off
15739         set_cache writethrough off
15740         test_155_small_load
15741         restore_lustre_params < $p
15742         rm -f $p
15743 }
15744 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15745
15746 test_155e() {
15747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15748
15749         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15750
15751         save_writethrough $p
15752
15753         set_cache read on
15754         set_cache writethrough on
15755         test_155_big_load
15756         restore_lustre_params < $p
15757         rm -f $p
15758 }
15759 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15760
15761 test_155f() {
15762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15763
15764         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15765
15766         save_writethrough $p
15767
15768         set_cache read on
15769         set_cache writethrough off
15770         test_155_big_load
15771         restore_lustre_params < $p
15772         rm -f $p
15773 }
15774 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15775
15776 test_155g() {
15777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15778
15779         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15780
15781         save_writethrough $p
15782
15783         set_cache read off
15784         set_cache writethrough on
15785         test_155_big_load
15786         restore_lustre_params < $p
15787         rm -f $p
15788 }
15789 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15790
15791 test_155h() {
15792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15793
15794         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15795
15796         save_writethrough $p
15797
15798         set_cache read off
15799         set_cache writethrough off
15800         test_155_big_load
15801         restore_lustre_params < $p
15802         rm -f $p
15803 }
15804 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15805
15806 test_156() {
15807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15808         remote_ost_nodsh && skip "remote OST with nodsh"
15809         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15810                 skip "stats not implemented on old servers"
15811         [ "$ost1_FSTYPE" = "zfs" ] &&
15812                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15813
15814         local CPAGES=3
15815         local BEFORE
15816         local AFTER
15817         local file="$DIR/$tfile"
15818         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15819
15820         save_writethrough $p
15821         roc_hit_init
15822
15823         log "Turn on read and write cache"
15824         set_cache read on
15825         set_cache writethrough on
15826
15827         log "Write data and read it back."
15828         log "Read should be satisfied from the cache."
15829         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15830         BEFORE=$(roc_hit)
15831         cancel_lru_locks osc
15832         cat $file >/dev/null
15833         AFTER=$(roc_hit)
15834         if ! let "AFTER - BEFORE == CPAGES"; then
15835                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15836         else
15837                 log "cache hits: before: $BEFORE, after: $AFTER"
15838         fi
15839
15840         log "Read again; it should be satisfied from the cache."
15841         BEFORE=$AFTER
15842         cancel_lru_locks osc
15843         cat $file >/dev/null
15844         AFTER=$(roc_hit)
15845         if ! let "AFTER - BEFORE == CPAGES"; then
15846                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15847         else
15848                 log "cache hits:: before: $BEFORE, after: $AFTER"
15849         fi
15850
15851         log "Turn off the read cache and turn on the write cache"
15852         set_cache read off
15853         set_cache writethrough on
15854
15855         log "Read again; it should be satisfied from the cache."
15856         BEFORE=$(roc_hit)
15857         cancel_lru_locks osc
15858         cat $file >/dev/null
15859         AFTER=$(roc_hit)
15860         if ! let "AFTER - BEFORE == CPAGES"; then
15861                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15862         else
15863                 log "cache hits:: before: $BEFORE, after: $AFTER"
15864         fi
15865
15866         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15867                 # > 2.12.56 uses pagecache if cached
15868                 log "Read again; it should not be satisfied from the cache."
15869                 BEFORE=$AFTER
15870                 cancel_lru_locks osc
15871                 cat $file >/dev/null
15872                 AFTER=$(roc_hit)
15873                 if ! let "AFTER - BEFORE == 0"; then
15874                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15875                 else
15876                         log "cache hits:: before: $BEFORE, after: $AFTER"
15877                 fi
15878         fi
15879
15880         log "Write data and read it back."
15881         log "Read should be satisfied from the cache."
15882         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15883         BEFORE=$(roc_hit)
15884         cancel_lru_locks osc
15885         cat $file >/dev/null
15886         AFTER=$(roc_hit)
15887         if ! let "AFTER - BEFORE == CPAGES"; then
15888                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15889         else
15890                 log "cache hits:: before: $BEFORE, after: $AFTER"
15891         fi
15892
15893         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15894                 # > 2.12.56 uses pagecache if cached
15895                 log "Read again; it should not be satisfied from the cache."
15896                 BEFORE=$AFTER
15897                 cancel_lru_locks osc
15898                 cat $file >/dev/null
15899                 AFTER=$(roc_hit)
15900                 if ! let "AFTER - BEFORE == 0"; then
15901                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15902                 else
15903                         log "cache hits:: before: $BEFORE, after: $AFTER"
15904                 fi
15905         fi
15906
15907         log "Turn off read and write cache"
15908         set_cache read off
15909         set_cache writethrough off
15910
15911         log "Write data and read it back"
15912         log "It should not be satisfied from the cache."
15913         rm -f $file
15914         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15915         cancel_lru_locks osc
15916         BEFORE=$(roc_hit)
15917         cat $file >/dev/null
15918         AFTER=$(roc_hit)
15919         if ! let "AFTER - BEFORE == 0"; then
15920                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15921         else
15922                 log "cache hits:: before: $BEFORE, after: $AFTER"
15923         fi
15924
15925         log "Turn on the read cache and turn off the write cache"
15926         set_cache read on
15927         set_cache writethrough off
15928
15929         log "Write data and read it back"
15930         log "It should not be satisfied from the cache."
15931         rm -f $file
15932         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15933         BEFORE=$(roc_hit)
15934         cancel_lru_locks osc
15935         cat $file >/dev/null
15936         AFTER=$(roc_hit)
15937         if ! let "AFTER - BEFORE == 0"; then
15938                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15939         else
15940                 log "cache hits:: before: $BEFORE, after: $AFTER"
15941         fi
15942
15943         log "Read again; it should be satisfied from the cache."
15944         BEFORE=$(roc_hit)
15945         cancel_lru_locks osc
15946         cat $file >/dev/null
15947         AFTER=$(roc_hit)
15948         if ! let "AFTER - BEFORE == CPAGES"; then
15949                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15950         else
15951                 log "cache hits:: before: $BEFORE, after: $AFTER"
15952         fi
15953
15954         restore_lustre_params < $p
15955         rm -f $p $file
15956 }
15957 run_test 156 "Verification of tunables"
15958
15959 test_160a() {
15960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15961         remote_mds_nodsh && skip "remote MDS with nodsh"
15962         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15963                 skip "Need MDS version at least 2.2.0"
15964
15965         changelog_register || error "changelog_register failed"
15966         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15967         changelog_users $SINGLEMDS | grep -q $cl_user ||
15968                 error "User $cl_user not found in changelog_users"
15969
15970         mkdir_on_mdt0 $DIR/$tdir
15971
15972         # change something
15973         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15974         changelog_clear 0 || error "changelog_clear failed"
15975         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15976         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15977         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15978         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15979         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15980         rm $DIR/$tdir/pics/desktop.jpg
15981
15982         echo "verifying changelog mask"
15983         changelog_chmask "-MKDIR"
15984         changelog_chmask "-CLOSE"
15985
15986         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15987         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15988
15989         changelog_chmask "+MKDIR"
15990         changelog_chmask "+CLOSE"
15991
15992         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15993         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15994
15995         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15996         CLOSES=$(changelog_dump | grep -c "CLOSE")
15997         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15998         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15999
16000         # verify contents
16001         echo "verifying target fid"
16002         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16003         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16004         [ "$fidc" == "$fidf" ] ||
16005                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16006         echo "verifying parent fid"
16007         # The FID returned from the Changelog may be the directory shard on
16008         # a different MDT, and not the FID returned by path2fid on the parent.
16009         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16010         # since this is what will matter when recreating this file in the tree.
16011         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16012         local pathp=$($LFS fid2path $MOUNT "$fidp")
16013         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16014                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16015
16016         echo "getting records for $cl_user"
16017         changelog_users $SINGLEMDS
16018         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16019         local nclr=3
16020         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16021                 error "changelog_clear failed"
16022         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16023         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16024         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16025                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16026
16027         local min0_rec=$(changelog_users $SINGLEMDS |
16028                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16029         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16030                           awk '{ print $1; exit; }')
16031
16032         changelog_dump | tail -n 5
16033         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16034         [ $first_rec == $((min0_rec + 1)) ] ||
16035                 error "first index should be $min0_rec + 1 not $first_rec"
16036
16037         # LU-3446 changelog index reset on MDT restart
16038         local cur_rec1=$(changelog_users $SINGLEMDS |
16039                          awk '/^current.index:/ { print $NF }')
16040         changelog_clear 0 ||
16041                 error "clear all changelog records for $cl_user failed"
16042         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16043         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16044                 error "Fail to start $SINGLEMDS"
16045         local cur_rec2=$(changelog_users $SINGLEMDS |
16046                          awk '/^current.index:/ { print $NF }')
16047         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16048         [ $cur_rec1 == $cur_rec2 ] ||
16049                 error "current index should be $cur_rec1 not $cur_rec2"
16050
16051         echo "verifying users from this test are deregistered"
16052         changelog_deregister || error "changelog_deregister failed"
16053         changelog_users $SINGLEMDS | grep -q $cl_user &&
16054                 error "User '$cl_user' still in changelog_users"
16055
16056         # lctl get_param -n mdd.*.changelog_users
16057         # current_index: 144
16058         # ID    index (idle seconds)
16059         # cl3   144   (2) mask=<list>
16060         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16061                 # this is the normal case where all users were deregistered
16062                 # make sure no new records are added when no users are present
16063                 local last_rec1=$(changelog_users $SINGLEMDS |
16064                                   awk '/^current.index:/ { print $NF }')
16065                 touch $DIR/$tdir/chloe
16066                 local last_rec2=$(changelog_users $SINGLEMDS |
16067                                   awk '/^current.index:/ { print $NF }')
16068                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16069                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16070         else
16071                 # any changelog users must be leftovers from a previous test
16072                 changelog_users $SINGLEMDS
16073                 echo "other changelog users; can't verify off"
16074         fi
16075 }
16076 run_test 160a "changelog sanity"
16077
16078 test_160b() { # LU-3587
16079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16080         remote_mds_nodsh && skip "remote MDS with nodsh"
16081         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16082                 skip "Need MDS version at least 2.2.0"
16083
16084         changelog_register || error "changelog_register failed"
16085         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16086         changelog_users $SINGLEMDS | grep -q $cl_user ||
16087                 error "User '$cl_user' not found in changelog_users"
16088
16089         local longname1=$(str_repeat a 255)
16090         local longname2=$(str_repeat b 255)
16091
16092         cd $DIR
16093         echo "creating very long named file"
16094         touch $longname1 || error "create of '$longname1' failed"
16095         echo "renaming very long named file"
16096         mv $longname1 $longname2
16097
16098         changelog_dump | grep RENME | tail -n 5
16099         rm -f $longname2
16100 }
16101 run_test 160b "Verify that very long rename doesn't crash in changelog"
16102
16103 test_160c() {
16104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16105         remote_mds_nodsh && skip "remote MDS with nodsh"
16106
16107         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16108                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16109                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16110                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16111
16112         local rc=0
16113
16114         # Registration step
16115         changelog_register || error "changelog_register failed"
16116
16117         rm -rf $DIR/$tdir
16118         mkdir -p $DIR/$tdir
16119         $MCREATE $DIR/$tdir/foo_160c
16120         changelog_chmask "-TRUNC"
16121         $TRUNCATE $DIR/$tdir/foo_160c 200
16122         changelog_chmask "+TRUNC"
16123         $TRUNCATE $DIR/$tdir/foo_160c 199
16124         changelog_dump | tail -n 5
16125         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16126         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16127 }
16128 run_test 160c "verify that changelog log catch the truncate event"
16129
16130 test_160d() {
16131         remote_mds_nodsh && skip "remote MDS with nodsh"
16132         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16134         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16135                 skip "Need MDS version at least 2.7.60"
16136
16137         # Registration step
16138         changelog_register || error "changelog_register failed"
16139
16140         mkdir -p $DIR/$tdir/migrate_dir
16141         changelog_clear 0 || error "changelog_clear failed"
16142
16143         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16144         changelog_dump | tail -n 5
16145         local migrates=$(changelog_dump | grep -c "MIGRT")
16146         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16147 }
16148 run_test 160d "verify that changelog log catch the migrate event"
16149
16150 test_160e() {
16151         remote_mds_nodsh && skip "remote MDS with nodsh"
16152
16153         # Create a user
16154         changelog_register || error "changelog_register failed"
16155
16156         local MDT0=$(facet_svc $SINGLEMDS)
16157         local rc
16158
16159         # No user (expect fail)
16160         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16161         rc=$?
16162         if [ $rc -eq 0 ]; then
16163                 error "Should fail without user"
16164         elif [ $rc -ne 4 ]; then
16165                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16166         fi
16167
16168         # Delete a future user (expect fail)
16169         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16170         rc=$?
16171         if [ $rc -eq 0 ]; then
16172                 error "Deleted non-existant user cl77"
16173         elif [ $rc -ne 2 ]; then
16174                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16175         fi
16176
16177         # Clear to a bad index (1 billion should be safe)
16178         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16179         rc=$?
16180
16181         if [ $rc -eq 0 ]; then
16182                 error "Successfully cleared to invalid CL index"
16183         elif [ $rc -ne 22 ]; then
16184                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16185         fi
16186 }
16187 run_test 160e "changelog negative testing (should return errors)"
16188
16189 test_160f() {
16190         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16191         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16192                 skip "Need MDS version at least 2.10.56"
16193
16194         local mdts=$(comma_list $(mdts_nodes))
16195
16196         # Create a user
16197         changelog_register || error "first changelog_register failed"
16198         changelog_register || error "second changelog_register failed"
16199         local cl_users
16200         declare -A cl_user1
16201         declare -A cl_user2
16202         local user_rec1
16203         local user_rec2
16204         local i
16205
16206         # generate some changelog records to accumulate on each MDT
16207         # use all_char because created files should be evenly distributed
16208         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16209                 error "test_mkdir $tdir failed"
16210         log "$(date +%s): creating first files"
16211         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16212                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16213                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16214         done
16215
16216         # check changelogs have been generated
16217         local start=$SECONDS
16218         local idle_time=$((MDSCOUNT * 5 + 5))
16219         local nbcl=$(changelog_dump | wc -l)
16220         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16221
16222         for param in "changelog_max_idle_time=$idle_time" \
16223                      "changelog_gc=1" \
16224                      "changelog_min_gc_interval=2" \
16225                      "changelog_min_free_cat_entries=3"; do
16226                 local MDT0=$(facet_svc $SINGLEMDS)
16227                 local var="${param%=*}"
16228                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16229
16230                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16231                 do_nodes $mdts $LCTL set_param mdd.*.$param
16232         done
16233
16234         # force cl_user2 to be idle (1st part), but also cancel the
16235         # cl_user1 records so that it is not evicted later in the test.
16236         local sleep1=$((idle_time / 2))
16237         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16238         sleep $sleep1
16239
16240         # simulate changelog catalog almost full
16241         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16242         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16243
16244         for i in $(seq $MDSCOUNT); do
16245                 cl_users=(${CL_USERS[mds$i]})
16246                 cl_user1[mds$i]="${cl_users[0]}"
16247                 cl_user2[mds$i]="${cl_users[1]}"
16248
16249                 [ -n "${cl_user1[mds$i]}" ] ||
16250                         error "mds$i: no user registered"
16251                 [ -n "${cl_user2[mds$i]}" ] ||
16252                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16253
16254                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16255                 [ -n "$user_rec1" ] ||
16256                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16257                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16258                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16259                 [ -n "$user_rec2" ] ||
16260                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16261                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16262                      "$user_rec1 + 2 == $user_rec2"
16263                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16264                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16265                               "$user_rec1 + 2, but is $user_rec2"
16266                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16267                 [ -n "$user_rec2" ] ||
16268                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16269                 [ $user_rec1 == $user_rec2 ] ||
16270                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16271                               "$user_rec1, but is $user_rec2"
16272         done
16273
16274         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16275         local sleep2=$((idle_time - (SECONDS - start) + 1))
16276         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16277         sleep $sleep2
16278
16279         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16280         # cl_user1 should be OK because it recently processed records.
16281         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16282         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16283                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16284                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16285         done
16286
16287         # ensure gc thread is done
16288         for i in $(mdts_nodes); do
16289                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16290                         error "$i: GC-thread not done"
16291         done
16292
16293         local first_rec
16294         for (( i = 1; i <= MDSCOUNT; i++ )); do
16295                 # check cl_user1 still registered
16296                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16297                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16298                 # check cl_user2 unregistered
16299                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16300                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16301
16302                 # check changelogs are present and starting at $user_rec1 + 1
16303                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16304                 [ -n "$user_rec1" ] ||
16305                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16306                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16307                             awk '{ print $1; exit; }')
16308
16309                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16310                 [ $((user_rec1 + 1)) == $first_rec ] ||
16311                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16312         done
16313 }
16314 run_test 160f "changelog garbage collect (timestamped users)"
16315
16316 test_160g() {
16317         remote_mds_nodsh && skip "remote MDS with nodsh"
16318         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16319                 skip "Need MDS version at least 2.14.55"
16320
16321         local mdts=$(comma_list $(mdts_nodes))
16322
16323         # Create a user
16324         changelog_register || error "first changelog_register failed"
16325         changelog_register || error "second changelog_register failed"
16326         local cl_users
16327         declare -A cl_user1
16328         declare -A cl_user2
16329         local user_rec1
16330         local user_rec2
16331         local i
16332
16333         # generate some changelog records to accumulate on each MDT
16334         # use all_char because created files should be evenly distributed
16335         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16336                 error "test_mkdir $tdir failed"
16337         for ((i = 0; i < MDSCOUNT; i++)); do
16338                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16339                         error "create $DIR/$tdir/d$i.1 failed"
16340         done
16341
16342         # check changelogs have been generated
16343         local nbcl=$(changelog_dump | wc -l)
16344         (( $nbcl > 0 )) || error "no changelogs found"
16345
16346         # reduce the max_idle_indexes value to make sure we exceed it
16347         for param in "changelog_max_idle_indexes=2" \
16348                      "changelog_gc=1" \
16349                      "changelog_min_gc_interval=2"; do
16350                 local MDT0=$(facet_svc $SINGLEMDS)
16351                 local var="${param%=*}"
16352                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16353
16354                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16355                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16356                         error "unable to set mdd.*.$param"
16357         done
16358
16359         local start=$SECONDS
16360         for i in $(seq $MDSCOUNT); do
16361                 cl_users=(${CL_USERS[mds$i]})
16362                 cl_user1[mds$i]="${cl_users[0]}"
16363                 cl_user2[mds$i]="${cl_users[1]}"
16364
16365                 [ -n "${cl_user1[mds$i]}" ] ||
16366                         error "mds$i: user1 is not registered"
16367                 [ -n "${cl_user2[mds$i]}" ] ||
16368                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16369
16370                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16371                 [ -n "$user_rec1" ] ||
16372                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16373                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16374                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16375                 [ -n "$user_rec2" ] ||
16376                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16377                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16378                      "$user_rec1 + 2 == $user_rec2"
16379                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16380                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16381                               "expected $user_rec1 + 2, but is $user_rec2"
16382                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16383                 [ -n "$user_rec2" ] ||
16384                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16385                 [ $user_rec1 == $user_rec2 ] ||
16386                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16387                               "expected $user_rec1, but is $user_rec2"
16388         done
16389
16390         # ensure we are past the previous changelog_min_gc_interval set above
16391         local sleep2=$((start + 2 - SECONDS))
16392         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16393         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16394         # cl_user1 should be OK because it recently processed records.
16395         for ((i = 0; i < MDSCOUNT; i++)); do
16396                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16397                         error "create $DIR/$tdir/d$i.3 failed"
16398         done
16399
16400         # ensure gc thread is done
16401         for i in $(mdts_nodes); do
16402                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16403                         error "$i: GC-thread not done"
16404         done
16405
16406         local first_rec
16407         for (( i = 1; i <= MDSCOUNT; i++ )); do
16408                 # check cl_user1 still registered
16409                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16410                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16411                 # check cl_user2 unregistered
16412                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16413                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16414
16415                 # check changelogs are present and starting at $user_rec1 + 1
16416                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16417                 [ -n "$user_rec1" ] ||
16418                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16419                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16420                             awk '{ print $1; exit; }')
16421
16422                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16423                 [ $((user_rec1 + 1)) == $first_rec ] ||
16424                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16425         done
16426 }
16427 run_test 160g "changelog garbage collect on idle records"
16428
16429 test_160h() {
16430         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16431         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16432                 skip "Need MDS version at least 2.10.56"
16433
16434         local mdts=$(comma_list $(mdts_nodes))
16435
16436         # Create a user
16437         changelog_register || error "first changelog_register failed"
16438         changelog_register || error "second changelog_register failed"
16439         local cl_users
16440         declare -A cl_user1
16441         declare -A cl_user2
16442         local user_rec1
16443         local user_rec2
16444         local i
16445
16446         # generate some changelog records to accumulate on each MDT
16447         # use all_char because created files should be evenly distributed
16448         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16449                 error "test_mkdir $tdir failed"
16450         for ((i = 0; i < MDSCOUNT; i++)); do
16451                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16452                         error "create $DIR/$tdir/d$i.1 failed"
16453         done
16454
16455         # check changelogs have been generated
16456         local nbcl=$(changelog_dump | wc -l)
16457         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16458
16459         for param in "changelog_max_idle_time=10" \
16460                      "changelog_gc=1" \
16461                      "changelog_min_gc_interval=2"; do
16462                 local MDT0=$(facet_svc $SINGLEMDS)
16463                 local var="${param%=*}"
16464                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16465
16466                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16467                 do_nodes $mdts $LCTL set_param mdd.*.$param
16468         done
16469
16470         # force cl_user2 to be idle (1st part)
16471         sleep 9
16472
16473         for i in $(seq $MDSCOUNT); do
16474                 cl_users=(${CL_USERS[mds$i]})
16475                 cl_user1[mds$i]="${cl_users[0]}"
16476                 cl_user2[mds$i]="${cl_users[1]}"
16477
16478                 [ -n "${cl_user1[mds$i]}" ] ||
16479                         error "mds$i: no user registered"
16480                 [ -n "${cl_user2[mds$i]}" ] ||
16481                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16482
16483                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16484                 [ -n "$user_rec1" ] ||
16485                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16486                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16487                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16488                 [ -n "$user_rec2" ] ||
16489                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16490                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16491                      "$user_rec1 + 2 == $user_rec2"
16492                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16493                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16494                               "$user_rec1 + 2, but is $user_rec2"
16495                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16496                 [ -n "$user_rec2" ] ||
16497                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16498                 [ $user_rec1 == $user_rec2 ] ||
16499                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16500                               "$user_rec1, but is $user_rec2"
16501         done
16502
16503         # force cl_user2 to be idle (2nd part) and to reach
16504         # changelog_max_idle_time
16505         sleep 2
16506
16507         # force each GC-thread start and block then
16508         # one per MDT/MDD, set fail_val accordingly
16509         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16510         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16511
16512         # generate more changelogs to trigger fail_loc
16513         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16514                 error "create $DIR/$tdir/${tfile}bis failed"
16515
16516         # stop MDT to stop GC-thread, should be done in back-ground as it will
16517         # block waiting for the thread to be released and exit
16518         declare -A stop_pids
16519         for i in $(seq $MDSCOUNT); do
16520                 stop mds$i &
16521                 stop_pids[mds$i]=$!
16522         done
16523
16524         for i in $(mdts_nodes); do
16525                 local facet
16526                 local nb=0
16527                 local facets=$(facets_up_on_host $i)
16528
16529                 for facet in ${facets//,/ }; do
16530                         if [[ $facet == mds* ]]; then
16531                                 nb=$((nb + 1))
16532                         fi
16533                 done
16534                 # ensure each MDS's gc threads are still present and all in "R"
16535                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16536                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16537                         error "$i: expected $nb GC-thread"
16538                 wait_update $i \
16539                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16540                         "R" 20 ||
16541                         error "$i: GC-thread not found in R-state"
16542                 # check umounts of each MDT on MDS have reached kthread_stop()
16543                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16544                         error "$i: expected $nb umount"
16545                 wait_update $i \
16546                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16547                         error "$i: umount not found in D-state"
16548         done
16549
16550         # release all GC-threads
16551         do_nodes $mdts $LCTL set_param fail_loc=0
16552
16553         # wait for MDT stop to complete
16554         for i in $(seq $MDSCOUNT); do
16555                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16556         done
16557
16558         # XXX
16559         # may try to check if any orphan changelog records are present
16560         # via ldiskfs/zfs and llog_reader...
16561
16562         # re-start/mount MDTs
16563         for i in $(seq $MDSCOUNT); do
16564                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16565                         error "Fail to start mds$i"
16566         done
16567
16568         local first_rec
16569         for i in $(seq $MDSCOUNT); do
16570                 # check cl_user1 still registered
16571                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16572                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16573                 # check cl_user2 unregistered
16574                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16575                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16576
16577                 # check changelogs are present and starting at $user_rec1 + 1
16578                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16579                 [ -n "$user_rec1" ] ||
16580                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16581                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16582                             awk '{ print $1; exit; }')
16583
16584                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16585                 [ $((user_rec1 + 1)) == $first_rec ] ||
16586                         error "mds$i: first index should be $user_rec1 + 1, " \
16587                               "but is $first_rec"
16588         done
16589 }
16590 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16591               "during mount"
16592
16593 test_160i() {
16594
16595         local mdts=$(comma_list $(mdts_nodes))
16596
16597         changelog_register || error "first changelog_register failed"
16598
16599         # generate some changelog records to accumulate on each MDT
16600         # use all_char because created files should be evenly distributed
16601         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16602                 error "test_mkdir $tdir failed"
16603         for ((i = 0; i < MDSCOUNT; i++)); do
16604                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16605                         error "create $DIR/$tdir/d$i.1 failed"
16606         done
16607
16608         # check changelogs have been generated
16609         local nbcl=$(changelog_dump | wc -l)
16610         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16611
16612         # simulate race between register and unregister
16613         # XXX as fail_loc is set per-MDS, with DNE configs the race
16614         # simulation will only occur for one MDT per MDS and for the
16615         # others the normal race scenario will take place
16616         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16617         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16618         do_nodes $mdts $LCTL set_param fail_val=1
16619
16620         # unregister 1st user
16621         changelog_deregister &
16622         local pid1=$!
16623         # wait some time for deregister work to reach race rdv
16624         sleep 2
16625         # register 2nd user
16626         changelog_register || error "2nd user register failed"
16627
16628         wait $pid1 || error "1st user deregister failed"
16629
16630         local i
16631         local last_rec
16632         declare -A LAST_REC
16633         for i in $(seq $MDSCOUNT); do
16634                 if changelog_users mds$i | grep "^cl"; then
16635                         # make sure new records are added with one user present
16636                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16637                                           awk '/^current.index:/ { print $NF }')
16638                 else
16639                         error "mds$i has no user registered"
16640                 fi
16641         done
16642
16643         # generate more changelog records to accumulate on each MDT
16644         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16645                 error "create $DIR/$tdir/${tfile}bis failed"
16646
16647         for i in $(seq $MDSCOUNT); do
16648                 last_rec=$(changelog_users $SINGLEMDS |
16649                            awk '/^current.index:/ { print $NF }')
16650                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16651                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16652                         error "changelogs are off on mds$i"
16653         done
16654 }
16655 run_test 160i "changelog user register/unregister race"
16656
16657 test_160j() {
16658         remote_mds_nodsh && skip "remote MDS with nodsh"
16659         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16660                 skip "Need MDS version at least 2.12.56"
16661
16662         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16663         stack_trap "umount $MOUNT2" EXIT
16664
16665         changelog_register || error "first changelog_register failed"
16666         stack_trap "changelog_deregister" EXIT
16667
16668         # generate some changelog
16669         # use all_char because created files should be evenly distributed
16670         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16671                 error "mkdir $tdir failed"
16672         for ((i = 0; i < MDSCOUNT; i++)); do
16673                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16674                         error "create $DIR/$tdir/d$i.1 failed"
16675         done
16676
16677         # open the changelog device
16678         exec 3>/dev/changelog-$FSNAME-MDT0000
16679         stack_trap "exec 3>&-" EXIT
16680         exec 4</dev/changelog-$FSNAME-MDT0000
16681         stack_trap "exec 4<&-" EXIT
16682
16683         # umount the first lustre mount
16684         umount $MOUNT
16685         stack_trap "mount_client $MOUNT" EXIT
16686
16687         # read changelog, which may or may not fail, but should not crash
16688         cat <&4 >/dev/null
16689
16690         # clear changelog
16691         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16692         changelog_users $SINGLEMDS | grep -q $cl_user ||
16693                 error "User $cl_user not found in changelog_users"
16694
16695         printf 'clear:'$cl_user':0' >&3
16696 }
16697 run_test 160j "client can be umounted while its chanangelog is being used"
16698
16699 test_160k() {
16700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16701         remote_mds_nodsh && skip "remote MDS with nodsh"
16702
16703         mkdir -p $DIR/$tdir/1/1
16704
16705         changelog_register || error "changelog_register failed"
16706         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16707
16708         changelog_users $SINGLEMDS | grep -q $cl_user ||
16709                 error "User '$cl_user' not found in changelog_users"
16710 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16711         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16712         rmdir $DIR/$tdir/1/1 & sleep 1
16713         mkdir $DIR/$tdir/2
16714         touch $DIR/$tdir/2/2
16715         rm -rf $DIR/$tdir/2
16716
16717         wait
16718         sleep 4
16719
16720         changelog_dump | grep rmdir || error "rmdir not recorded"
16721 }
16722 run_test 160k "Verify that changelog records are not lost"
16723
16724 # Verifies that a file passed as a parameter has recently had an operation
16725 # performed on it that has generated an MTIME changelog which contains the
16726 # correct parent FID. As files might reside on a different MDT from the
16727 # parent directory in DNE configurations, the FIDs are translated to paths
16728 # before being compared, which should be identical
16729 compare_mtime_changelog() {
16730         local file="${1}"
16731         local mdtidx
16732         local mtime
16733         local cl_fid
16734         local pdir
16735         local dir
16736
16737         mdtidx=$($LFS getstripe --mdt-index $file)
16738         mdtidx=$(printf "%04x" $mdtidx)
16739
16740         # Obtain the parent FID from the MTIME changelog
16741         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16742         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16743
16744         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16745         [ -z "$cl_fid" ] && error "parent FID not present"
16746
16747         # Verify that the path for the parent FID is the same as the path for
16748         # the test directory
16749         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16750
16751         dir=$(dirname $1)
16752
16753         [[ "${pdir%/}" == "$dir" ]] ||
16754                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16755 }
16756
16757 test_160l() {
16758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16759
16760         remote_mds_nodsh && skip "remote MDS with nodsh"
16761         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16762                 skip "Need MDS version at least 2.13.55"
16763
16764         local cl_user
16765
16766         changelog_register || error "changelog_register failed"
16767         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16768
16769         changelog_users $SINGLEMDS | grep -q $cl_user ||
16770                 error "User '$cl_user' not found in changelog_users"
16771
16772         # Clear some types so that MTIME changelogs are generated
16773         changelog_chmask "-CREAT"
16774         changelog_chmask "-CLOSE"
16775
16776         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16777
16778         # Test CL_MTIME during setattr
16779         touch $DIR/$tdir/$tfile
16780         compare_mtime_changelog $DIR/$tdir/$tfile
16781
16782         # Test CL_MTIME during close
16783         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16784         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16785 }
16786 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16787
16788 test_160m() {
16789         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16790         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16791                 skip "Need MDS version at least 2.14.51"
16792         local cl_users
16793         local cl_user1
16794         local cl_user2
16795         local pid1
16796
16797         # Create a user
16798         changelog_register || error "first changelog_register failed"
16799         changelog_register || error "second changelog_register failed"
16800
16801         cl_users=(${CL_USERS[mds1]})
16802         cl_user1="${cl_users[0]}"
16803         cl_user2="${cl_users[1]}"
16804         # generate some changelog records to accumulate on MDT0
16805         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16806         createmany -m $DIR/$tdir/$tfile 50 ||
16807                 error "create $DIR/$tdir/$tfile failed"
16808         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16809         rm -f $DIR/$tdir
16810
16811         # check changelogs have been generated
16812         local nbcl=$(changelog_dump | wc -l)
16813         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16814
16815 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16816         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16817
16818         __changelog_clear mds1 $cl_user1 +10
16819         __changelog_clear mds1 $cl_user2 0 &
16820         pid1=$!
16821         sleep 2
16822         __changelog_clear mds1 $cl_user1 0 ||
16823                 error "fail to cancel record for $cl_user1"
16824         wait $pid1
16825         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16826 }
16827 run_test 160m "Changelog clear race"
16828
16829 test_160n() {
16830         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16831         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16832                 skip "Need MDS version at least 2.14.51"
16833         local cl_users
16834         local cl_user1
16835         local cl_user2
16836         local pid1
16837         local first_rec
16838         local last_rec=0
16839
16840         # Create a user
16841         changelog_register || error "first changelog_register failed"
16842
16843         cl_users=(${CL_USERS[mds1]})
16844         cl_user1="${cl_users[0]}"
16845
16846         # generate some changelog records to accumulate on MDT0
16847         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16848         first_rec=$(changelog_users $SINGLEMDS |
16849                         awk '/^current.index:/ { print $NF }')
16850         while (( last_rec < (( first_rec + 65000)) )); do
16851                 createmany -m $DIR/$tdir/$tfile 10000 ||
16852                         error "create $DIR/$tdir/$tfile failed"
16853
16854                 for i in $(seq 0 10000); do
16855                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16856                                 > /dev/null
16857                 done
16858
16859                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16860                         error "unlinkmany failed unlink"
16861                 last_rec=$(changelog_users $SINGLEMDS |
16862                         awk '/^current.index:/ { print $NF }')
16863                 echo last record $last_rec
16864                 (( last_rec == 0 )) && error "no changelog found"
16865         done
16866
16867 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16868         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16869
16870         __changelog_clear mds1 $cl_user1 0 &
16871         pid1=$!
16872         sleep 2
16873         __changelog_clear mds1 $cl_user1 0 ||
16874                 error "fail to cancel record for $cl_user1"
16875         wait $pid1
16876         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16877 }
16878 run_test 160n "Changelog destroy race"
16879
16880 test_160o() {
16881         local mdt="$(facet_svc $SINGLEMDS)"
16882
16883         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16884         remote_mds_nodsh && skip "remote MDS with nodsh"
16885         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16886                 skip "Need MDS version at least 2.14.52"
16887
16888         changelog_register --user test_160o -m unlnk+close+open ||
16889                 error "changelog_register failed"
16890
16891         do_facet $SINGLEMDS $LCTL --device $mdt \
16892                                 changelog_register -u "Tt3_-#" &&
16893                 error "bad symbols in name should fail"
16894
16895         do_facet $SINGLEMDS $LCTL --device $mdt \
16896                                 changelog_register -u test_160o &&
16897                 error "the same name registration should fail"
16898
16899         do_facet $SINGLEMDS $LCTL --device $mdt \
16900                         changelog_register -u test_160toolongname &&
16901                 error "too long name registration should fail"
16902
16903         changelog_chmask "MARK+HSM"
16904         lctl get_param mdd.*.changelog*mask
16905         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16906         changelog_users $SINGLEMDS | grep -q $cl_user ||
16907                 error "User $cl_user not found in changelog_users"
16908         #verify username
16909         echo $cl_user | grep -q test_160o ||
16910                 error "User $cl_user has no specific name 'test160o'"
16911
16912         # change something
16913         changelog_clear 0 || error "changelog_clear failed"
16914         # generate some changelog records to accumulate on MDT0
16915         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16916         touch $DIR/$tdir/$tfile                 # open 1
16917
16918         OPENS=$(changelog_dump | grep -c "OPEN")
16919         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16920
16921         # must be no MKDIR it wasn't set as user mask
16922         MKDIR=$(changelog_dump | grep -c "MKDIR")
16923         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16924
16925         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16926                                 mdd.$mdt.changelog_current_mask -n)
16927         # register maskless user
16928         changelog_register || error "changelog_register failed"
16929         # effective mask should be not changed because it is not minimal
16930         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16931                                 mdd.$mdt.changelog_current_mask -n)
16932         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16933         # set server mask to minimal value
16934         changelog_chmask "MARK"
16935         # check effective mask again, should be treated as DEFMASK now
16936         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16937                                 mdd.$mdt.changelog_current_mask -n)
16938         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16939
16940         do_facet $SINGLEMDS $LCTL --device $mdt \
16941                                 changelog_deregister -u test_160o ||
16942                 error "cannot deregister by name"
16943 }
16944 run_test 160o "changelog user name and mask"
16945
16946 test_160p() {
16947         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16948         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16949                 skip "Need MDS version at least 2.14.51"
16950         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16951         local cl_users
16952         local cl_user1
16953         local entry_count
16954
16955         # Create a user
16956         changelog_register || error "first changelog_register failed"
16957
16958         cl_users=(${CL_USERS[mds1]})
16959         cl_user1="${cl_users[0]}"
16960
16961         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16962         createmany -m $DIR/$tdir/$tfile 50 ||
16963                 error "create $DIR/$tdir/$tfile failed"
16964         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16965         rm -rf $DIR/$tdir
16966
16967         # check changelogs have been generated
16968         entry_count=$(changelog_dump | wc -l)
16969         ((entry_count != 0)) || error "no changelog entries found"
16970
16971         # remove changelog_users and check that orphan entries are removed
16972         stop mds1
16973         local dev=$(mdsdevname 1)
16974         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16975         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16976         entry_count=$(changelog_dump | wc -l)
16977         ((entry_count == 0)) ||
16978                 error "found $entry_count changelog entries, expected none"
16979 }
16980 run_test 160p "Changelog orphan cleanup with no users"
16981
16982 test_160q() {
16983         local mdt="$(facet_svc $SINGLEMDS)"
16984         local clu
16985
16986         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16987         remote_mds_nodsh && skip "remote MDS with nodsh"
16988         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16989                 skip "Need MDS version at least 2.14.54"
16990
16991         # set server mask to minimal value like server init does
16992         changelog_chmask "MARK"
16993         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16994                 error "changelog_register failed"
16995         # check effective mask again, should be treated as DEFMASK now
16996         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16997                                 mdd.$mdt.changelog_current_mask -n)
16998         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16999                 error "changelog_deregister failed"
17000         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17001 }
17002 run_test 160q "changelog effective mask is DEFMASK if not set"
17003
17004 test_160s() {
17005         remote_mds_nodsh && skip "remote MDS with nodsh"
17006         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17007                 skip "Need MDS version at least 2.14.55"
17008
17009         local mdts=$(comma_list $(mdts_nodes))
17010
17011         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17012         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17013                                        fail_val=$((24 * 3600 * 10))
17014
17015         # Create a user which is 10 days old
17016         changelog_register || error "first changelog_register failed"
17017         local cl_users
17018         declare -A cl_user1
17019         local i
17020
17021         # generate some changelog records to accumulate on each MDT
17022         # use all_char because created files should be evenly distributed
17023         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17024                 error "test_mkdir $tdir failed"
17025         for ((i = 0; i < MDSCOUNT; i++)); do
17026                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17027                         error "create $DIR/$tdir/d$i.1 failed"
17028         done
17029
17030         # check changelogs have been generated
17031         local nbcl=$(changelog_dump | wc -l)
17032         (( nbcl > 0 )) || error "no changelogs found"
17033
17034         # reduce the max_idle_indexes value to make sure we exceed it
17035         for param in "changelog_max_idle_indexes=2097446912" \
17036                      "changelog_max_idle_time=2592000" \
17037                      "changelog_gc=1" \
17038                      "changelog_min_gc_interval=2"; do
17039                 local MDT0=$(facet_svc $SINGLEMDS)
17040                 local var="${param%=*}"
17041                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17042
17043                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17044                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17045                         error "unable to set mdd.*.$param"
17046         done
17047
17048         local start=$SECONDS
17049         for i in $(seq $MDSCOUNT); do
17050                 cl_users=(${CL_USERS[mds$i]})
17051                 cl_user1[mds$i]="${cl_users[0]}"
17052
17053                 [[ -n "${cl_user1[mds$i]}" ]] ||
17054                         error "mds$i: no user registered"
17055         done
17056
17057         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17058         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17059
17060         # ensure we are past the previous changelog_min_gc_interval set above
17061         local sleep2=$((start + 2 - SECONDS))
17062         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17063
17064         # Generate one more changelog to trigger GC
17065         for ((i = 0; i < MDSCOUNT; i++)); do
17066                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17067                         error "create $DIR/$tdir/d$i.3 failed"
17068         done
17069
17070         # ensure gc thread is done
17071         for node in $(mdts_nodes); do
17072                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17073                         error "$node: GC-thread not done"
17074         done
17075
17076         do_nodes $mdts $LCTL set_param fail_loc=0
17077
17078         for (( i = 1; i <= MDSCOUNT; i++ )); do
17079                 # check cl_user1 is purged
17080                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17081                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17082         done
17083         return 0
17084 }
17085 run_test 160s "changelog garbage collect on idle records * time"
17086
17087 test_161a() {
17088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17089
17090         test_mkdir -c1 $DIR/$tdir
17091         cp /etc/hosts $DIR/$tdir/$tfile
17092         test_mkdir -c1 $DIR/$tdir/foo1
17093         test_mkdir -c1 $DIR/$tdir/foo2
17094         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17095         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17096         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17097         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17098         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17099         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17100                 $LFS fid2path $DIR $FID
17101                 error "bad link ea"
17102         fi
17103         # middle
17104         rm $DIR/$tdir/foo2/zachary
17105         # last
17106         rm $DIR/$tdir/foo2/thor
17107         # first
17108         rm $DIR/$tdir/$tfile
17109         # rename
17110         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17111         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17112                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17113         rm $DIR/$tdir/foo2/maggie
17114
17115         # overflow the EA
17116         local longname=$tfile.avg_len_is_thirty_two_
17117         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17118                 error_noexit 'failed to unlink many hardlinks'" EXIT
17119         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17120                 error "failed to hardlink many files"
17121         links=$($LFS fid2path $DIR $FID | wc -l)
17122         echo -n "${links}/1000 links in link EA"
17123         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17124 }
17125 run_test 161a "link ea sanity"
17126
17127 test_161b() {
17128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17129         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17130
17131         local MDTIDX=1
17132         local remote_dir=$DIR/$tdir/remote_dir
17133
17134         mkdir -p $DIR/$tdir
17135         $LFS mkdir -i $MDTIDX $remote_dir ||
17136                 error "create remote directory failed"
17137
17138         cp /etc/hosts $remote_dir/$tfile
17139         mkdir -p $remote_dir/foo1
17140         mkdir -p $remote_dir/foo2
17141         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17142         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17143         ln $remote_dir/$tfile $remote_dir/foo1/luna
17144         ln $remote_dir/$tfile $remote_dir/foo2/thor
17145
17146         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17147                      tr -d ']')
17148         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17149                 $LFS fid2path $DIR $FID
17150                 error "bad link ea"
17151         fi
17152         # middle
17153         rm $remote_dir/foo2/zachary
17154         # last
17155         rm $remote_dir/foo2/thor
17156         # first
17157         rm $remote_dir/$tfile
17158         # rename
17159         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17160         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17161         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17162                 $LFS fid2path $DIR $FID
17163                 error "bad link rename"
17164         fi
17165         rm $remote_dir/foo2/maggie
17166
17167         # overflow the EA
17168         local longname=filename_avg_len_is_thirty_two_
17169         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17170                 error "failed to hardlink many files"
17171         links=$($LFS fid2path $DIR $FID | wc -l)
17172         echo -n "${links}/1000 links in link EA"
17173         [[ ${links} -gt 60 ]] ||
17174                 error "expected at least 60 links in link EA"
17175         unlinkmany $remote_dir/foo2/$longname 1000 ||
17176         error "failed to unlink many hardlinks"
17177 }
17178 run_test 161b "link ea sanity under remote directory"
17179
17180 test_161c() {
17181         remote_mds_nodsh && skip "remote MDS with nodsh"
17182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17183         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17184                 skip "Need MDS version at least 2.1.5"
17185
17186         # define CLF_RENAME_LAST 0x0001
17187         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17188         changelog_register || error "changelog_register failed"
17189
17190         rm -rf $DIR/$tdir
17191         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17192         touch $DIR/$tdir/foo_161c
17193         touch $DIR/$tdir/bar_161c
17194         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17195         changelog_dump | grep RENME | tail -n 5
17196         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17197         changelog_clear 0 || error "changelog_clear failed"
17198         if [ x$flags != "x0x1" ]; then
17199                 error "flag $flags is not 0x1"
17200         fi
17201
17202         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17203         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17204         touch $DIR/$tdir/foo_161c
17205         touch $DIR/$tdir/bar_161c
17206         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17207         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17208         changelog_dump | grep RENME | tail -n 5
17209         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17210         changelog_clear 0 || error "changelog_clear failed"
17211         if [ x$flags != "x0x0" ]; then
17212                 error "flag $flags is not 0x0"
17213         fi
17214         echo "rename overwrite a target having nlink > 1," \
17215                 "changelog record has flags of $flags"
17216
17217         # rename doesn't overwrite a target (changelog flag 0x0)
17218         touch $DIR/$tdir/foo_161c
17219         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17220         changelog_dump | grep RENME | tail -n 5
17221         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17222         changelog_clear 0 || error "changelog_clear failed"
17223         if [ x$flags != "x0x0" ]; then
17224                 error "flag $flags is not 0x0"
17225         fi
17226         echo "rename doesn't overwrite a target," \
17227                 "changelog record has flags of $flags"
17228
17229         # define CLF_UNLINK_LAST 0x0001
17230         # unlink a file having nlink = 1 (changelog flag 0x1)
17231         rm -f $DIR/$tdir/foo2_161c
17232         changelog_dump | grep UNLNK | tail -n 5
17233         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17234         changelog_clear 0 || error "changelog_clear failed"
17235         if [ x$flags != "x0x1" ]; then
17236                 error "flag $flags is not 0x1"
17237         fi
17238         echo "unlink a file having nlink = 1," \
17239                 "changelog record has flags of $flags"
17240
17241         # unlink a file having nlink > 1 (changelog flag 0x0)
17242         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17243         rm -f $DIR/$tdir/foobar_161c
17244         changelog_dump | grep UNLNK | tail -n 5
17245         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17246         changelog_clear 0 || error "changelog_clear failed"
17247         if [ x$flags != "x0x0" ]; then
17248                 error "flag $flags is not 0x0"
17249         fi
17250         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17251 }
17252 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17253
17254 test_161d() {
17255         remote_mds_nodsh && skip "remote MDS with nodsh"
17256         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17257
17258         local pid
17259         local fid
17260
17261         changelog_register || error "changelog_register failed"
17262
17263         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17264         # interfer with $MOUNT/.lustre/fid/ access
17265         mkdir $DIR/$tdir
17266         [[ $? -eq 0 ]] || error "mkdir failed"
17267
17268         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17269         $LCTL set_param fail_loc=0x8000140c
17270         # 5s pause
17271         $LCTL set_param fail_val=5
17272
17273         # create file
17274         echo foofoo > $DIR/$tdir/$tfile &
17275         pid=$!
17276
17277         # wait for create to be delayed
17278         sleep 2
17279
17280         ps -p $pid
17281         [[ $? -eq 0 ]] || error "create should be blocked"
17282
17283         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17284         stack_trap "rm -f $tempfile"
17285         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17286         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17287         # some delay may occur during ChangeLog publishing and file read just
17288         # above, that could allow file write to happen finally
17289         [[ -s $tempfile ]] && echo "file should be empty"
17290
17291         $LCTL set_param fail_loc=0
17292
17293         wait $pid
17294         [[ $? -eq 0 ]] || error "create failed"
17295 }
17296 run_test 161d "create with concurrent .lustre/fid access"
17297
17298 check_path() {
17299         local expected="$1"
17300         shift
17301         local fid="$2"
17302
17303         local path
17304         path=$($LFS fid2path "$@")
17305         local rc=$?
17306
17307         if [ $rc -ne 0 ]; then
17308                 error "path looked up of '$expected' failed: rc=$rc"
17309         elif [ "$path" != "$expected" ]; then
17310                 error "path looked up '$path' instead of '$expected'"
17311         else
17312                 echo "FID '$fid' resolves to path '$path' as expected"
17313         fi
17314 }
17315
17316 test_162a() { # was test_162
17317         test_mkdir -p -c1 $DIR/$tdir/d2
17318         touch $DIR/$tdir/d2/$tfile
17319         touch $DIR/$tdir/d2/x1
17320         touch $DIR/$tdir/d2/x2
17321         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17322         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17323         # regular file
17324         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17325         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17326
17327         # softlink
17328         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17329         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17330         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17331
17332         # softlink to wrong file
17333         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17334         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17335         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17336
17337         # hardlink
17338         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17339         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17340         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17341         # fid2path dir/fsname should both work
17342         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17343         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17344
17345         # hardlink count: check that there are 2 links
17346         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17347         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17348
17349         # hardlink indexing: remove the first link
17350         rm $DIR/$tdir/d2/p/q/r/hlink
17351         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17352 }
17353 run_test 162a "path lookup sanity"
17354
17355 test_162b() {
17356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17358
17359         mkdir $DIR/$tdir
17360         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17361                                 error "create striped dir failed"
17362
17363         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17364                                         tail -n 1 | awk '{print $2}')
17365         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17366
17367         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17368         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17369
17370         # regular file
17371         for ((i=0;i<5;i++)); do
17372                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17373                         error "get fid for f$i failed"
17374                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17375
17376                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17377                         error "get fid for d$i failed"
17378                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17379         done
17380
17381         return 0
17382 }
17383 run_test 162b "striped directory path lookup sanity"
17384
17385 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17386 test_162c() {
17387         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17388                 skip "Need MDS version at least 2.7.51"
17389
17390         local lpath=$tdir.local
17391         local rpath=$tdir.remote
17392
17393         test_mkdir $DIR/$lpath
17394         test_mkdir $DIR/$rpath
17395
17396         for ((i = 0; i <= 101; i++)); do
17397                 lpath="$lpath/$i"
17398                 mkdir $DIR/$lpath
17399                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17400                         error "get fid for local directory $DIR/$lpath failed"
17401                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17402
17403                 rpath="$rpath/$i"
17404                 test_mkdir $DIR/$rpath
17405                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17406                         error "get fid for remote directory $DIR/$rpath failed"
17407                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17408         done
17409
17410         return 0
17411 }
17412 run_test 162c "fid2path works with paths 100 or more directories deep"
17413
17414 oalr_event_count() {
17415         local event="${1}"
17416         local trace="${2}"
17417
17418         awk -v name="${FSNAME}-OST0000" \
17419             -v event="${event}" \
17420             '$1 == "TRACE" && $2 == event && $3 == name' \
17421             "${trace}" |
17422         wc -l
17423 }
17424
17425 oalr_expect_event_count() {
17426         local event="${1}"
17427         local trace="${2}"
17428         local expect="${3}"
17429         local count
17430
17431         count=$(oalr_event_count "${event}" "${trace}")
17432         if ((count == expect)); then
17433                 return 0
17434         fi
17435
17436         error_noexit "${event} event count was '${count}', expected ${expect}"
17437         cat "${trace}" >&2
17438         exit 1
17439 }
17440
17441 cleanup_165() {
17442         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17443         stop ost1
17444         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17445 }
17446
17447 setup_165() {
17448         sync # Flush previous IOs so we can count log entries.
17449         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17450         stack_trap cleanup_165 EXIT
17451 }
17452
17453 test_165a() {
17454         local trace="/tmp/${tfile}.trace"
17455         local rc
17456         local count
17457
17458         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17459                 skip "OFD access log unsupported"
17460
17461         setup_165
17462         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17463         sleep 5
17464
17465         do_facet ost1 ofd_access_log_reader --list
17466         stop ost1
17467
17468         do_facet ost1 killall -TERM ofd_access_log_reader
17469         wait
17470         rc=$?
17471
17472         if ((rc != 0)); then
17473                 error "ofd_access_log_reader exited with rc = '${rc}'"
17474         fi
17475
17476         # Parse trace file for discovery events:
17477         oalr_expect_event_count alr_log_add "${trace}" 1
17478         oalr_expect_event_count alr_log_eof "${trace}" 1
17479         oalr_expect_event_count alr_log_free "${trace}" 1
17480 }
17481 run_test 165a "ofd access log discovery"
17482
17483 test_165b() {
17484         local trace="/tmp/${tfile}.trace"
17485         local file="${DIR}/${tfile}"
17486         local pfid1
17487         local pfid2
17488         local -a entry
17489         local rc
17490         local count
17491         local size
17492         local flags
17493
17494         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17495                 skip "OFD access log unsupported"
17496
17497         setup_165
17498         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17499         sleep 5
17500
17501         do_facet ost1 ofd_access_log_reader --list
17502
17503         lfs setstripe -c 1 -i 0 "${file}"
17504         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17505                 error "cannot create '${file}'"
17506
17507         sleep 5
17508         do_facet ost1 killall -TERM ofd_access_log_reader
17509         wait
17510         rc=$?
17511
17512         if ((rc != 0)); then
17513                 error "ofd_access_log_reader exited with rc = '${rc}'"
17514         fi
17515
17516         oalr_expect_event_count alr_log_entry "${trace}" 1
17517
17518         pfid1=$($LFS path2fid "${file}")
17519
17520         # 1     2             3   4    5     6   7    8    9     10
17521         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17522         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17523
17524         echo "entry = '${entry[*]}'" >&2
17525
17526         pfid2=${entry[4]}
17527         if [[ "${pfid1}" != "${pfid2}" ]]; then
17528                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17529         fi
17530
17531         size=${entry[8]}
17532         if ((size != 1048576)); then
17533                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17534         fi
17535
17536         flags=${entry[10]}
17537         if [[ "${flags}" != "w" ]]; then
17538                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17539         fi
17540
17541         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17542         sleep 5
17543
17544         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17545                 error "cannot read '${file}'"
17546         sleep 5
17547
17548         do_facet ost1 killall -TERM ofd_access_log_reader
17549         wait
17550         rc=$?
17551
17552         if ((rc != 0)); then
17553                 error "ofd_access_log_reader exited with rc = '${rc}'"
17554         fi
17555
17556         oalr_expect_event_count alr_log_entry "${trace}" 1
17557
17558         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17559         echo "entry = '${entry[*]}'" >&2
17560
17561         pfid2=${entry[4]}
17562         if [[ "${pfid1}" != "${pfid2}" ]]; then
17563                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17564         fi
17565
17566         size=${entry[8]}
17567         if ((size != 524288)); then
17568                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17569         fi
17570
17571         flags=${entry[10]}
17572         if [[ "${flags}" != "r" ]]; then
17573                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17574         fi
17575 }
17576 run_test 165b "ofd access log entries are produced and consumed"
17577
17578 test_165c() {
17579         local trace="/tmp/${tfile}.trace"
17580         local file="${DIR}/${tdir}/${tfile}"
17581
17582         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17583                 skip "OFD access log unsupported"
17584
17585         test_mkdir "${DIR}/${tdir}"
17586
17587         setup_165
17588         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17589         sleep 5
17590
17591         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17592
17593         # 4096 / 64 = 64. Create twice as many entries.
17594         for ((i = 0; i < 128; i++)); do
17595                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17596                         error "cannot create file"
17597         done
17598
17599         sync
17600
17601         do_facet ost1 killall -TERM ofd_access_log_reader
17602         wait
17603         rc=$?
17604         if ((rc != 0)); then
17605                 error "ofd_access_log_reader exited with rc = '${rc}'"
17606         fi
17607
17608         unlinkmany  "${file}-%d" 128
17609 }
17610 run_test 165c "full ofd access logs do not block IOs"
17611
17612 oal_get_read_count() {
17613         local stats="$1"
17614
17615         # STATS lustre-OST0001 alr_read_count 1
17616
17617         do_facet ost1 cat "${stats}" |
17618         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17619              END { print count; }'
17620 }
17621
17622 oal_expect_read_count() {
17623         local stats="$1"
17624         local count
17625         local expect="$2"
17626
17627         # Ask ofd_access_log_reader to write stats.
17628         do_facet ost1 killall -USR1 ofd_access_log_reader
17629
17630         # Allow some time for things to happen.
17631         sleep 1
17632
17633         count=$(oal_get_read_count "${stats}")
17634         if ((count == expect)); then
17635                 return 0
17636         fi
17637
17638         error_noexit "bad read count, got ${count}, expected ${expect}"
17639         do_facet ost1 cat "${stats}" >&2
17640         exit 1
17641 }
17642
17643 test_165d() {
17644         local stats="/tmp/${tfile}.stats"
17645         local file="${DIR}/${tdir}/${tfile}"
17646         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17647
17648         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17649                 skip "OFD access log unsupported"
17650
17651         test_mkdir "${DIR}/${tdir}"
17652
17653         setup_165
17654         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17655         sleep 5
17656
17657         lfs setstripe -c 1 -i 0 "${file}"
17658
17659         do_facet ost1 lctl set_param "${param}=rw"
17660         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17661                 error "cannot create '${file}'"
17662         oal_expect_read_count "${stats}" 1
17663
17664         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17665                 error "cannot read '${file}'"
17666         oal_expect_read_count "${stats}" 2
17667
17668         do_facet ost1 lctl set_param "${param}=r"
17669         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17670                 error "cannot create '${file}'"
17671         oal_expect_read_count "${stats}" 2
17672
17673         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17674                 error "cannot read '${file}'"
17675         oal_expect_read_count "${stats}" 3
17676
17677         do_facet ost1 lctl set_param "${param}=w"
17678         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17679                 error "cannot create '${file}'"
17680         oal_expect_read_count "${stats}" 4
17681
17682         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17683                 error "cannot read '${file}'"
17684         oal_expect_read_count "${stats}" 4
17685
17686         do_facet ost1 lctl set_param "${param}=0"
17687         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17688                 error "cannot create '${file}'"
17689         oal_expect_read_count "${stats}" 4
17690
17691         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17692                 error "cannot read '${file}'"
17693         oal_expect_read_count "${stats}" 4
17694
17695         do_facet ost1 killall -TERM ofd_access_log_reader
17696         wait
17697         rc=$?
17698         if ((rc != 0)); then
17699                 error "ofd_access_log_reader exited with rc = '${rc}'"
17700         fi
17701 }
17702 run_test 165d "ofd_access_log mask works"
17703
17704 test_165e() {
17705         local stats="/tmp/${tfile}.stats"
17706         local file0="${DIR}/${tdir}-0/${tfile}"
17707         local file1="${DIR}/${tdir}-1/${tfile}"
17708
17709         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17710                 skip "OFD access log unsupported"
17711
17712         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17713
17714         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17715         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17716
17717         lfs setstripe -c 1 -i 0 "${file0}"
17718         lfs setstripe -c 1 -i 0 "${file1}"
17719
17720         setup_165
17721         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17722         sleep 5
17723
17724         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17725                 error "cannot create '${file0}'"
17726         sync
17727         oal_expect_read_count "${stats}" 0
17728
17729         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17730                 error "cannot create '${file1}'"
17731         sync
17732         oal_expect_read_count "${stats}" 1
17733
17734         do_facet ost1 killall -TERM ofd_access_log_reader
17735         wait
17736         rc=$?
17737         if ((rc != 0)); then
17738                 error "ofd_access_log_reader exited with rc = '${rc}'"
17739         fi
17740 }
17741 run_test 165e "ofd_access_log MDT index filter works"
17742
17743 test_165f() {
17744         local trace="/tmp/${tfile}.trace"
17745         local rc
17746         local count
17747
17748         setup_165
17749         do_facet ost1 timeout 60 ofd_access_log_reader \
17750                 --exit-on-close --debug=- --trace=- > "${trace}" &
17751         sleep 5
17752         stop ost1
17753
17754         wait
17755         rc=$?
17756
17757         if ((rc != 0)); then
17758                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17759                 cat "${trace}"
17760                 exit 1
17761         fi
17762 }
17763 run_test 165f "ofd_access_log_reader --exit-on-close works"
17764
17765 test_169() {
17766         # do directio so as not to populate the page cache
17767         log "creating a 10 Mb file"
17768         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17769                 error "multiop failed while creating a file"
17770         log "starting reads"
17771         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17772         log "truncating the file"
17773         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17774                 error "multiop failed while truncating the file"
17775         log "killing dd"
17776         kill %+ || true # reads might have finished
17777         echo "wait until dd is finished"
17778         wait
17779         log "removing the temporary file"
17780         rm -rf $DIR/$tfile || error "tmp file removal failed"
17781 }
17782 run_test 169 "parallel read and truncate should not deadlock"
17783
17784 test_170() {
17785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17786
17787         $LCTL clear     # bug 18514
17788         $LCTL debug_daemon start $TMP/${tfile}_log_good
17789         touch $DIR/$tfile
17790         $LCTL debug_daemon stop
17791         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17792                 error "sed failed to read log_good"
17793
17794         $LCTL debug_daemon start $TMP/${tfile}_log_good
17795         rm -rf $DIR/$tfile
17796         $LCTL debug_daemon stop
17797
17798         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17799                error "lctl df log_bad failed"
17800
17801         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17802         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17803
17804         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17805         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17806
17807         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17808                 error "bad_line good_line1 good_line2 are empty"
17809
17810         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17811         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17812         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17813
17814         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17815         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17816         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17817
17818         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17819                 error "bad_line_new good_line_new are empty"
17820
17821         local expected_good=$((good_line1 + good_line2*2))
17822
17823         rm -f $TMP/${tfile}*
17824         # LU-231, short malformed line may not be counted into bad lines
17825         if [ $bad_line -ne $bad_line_new ] &&
17826                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17827                 error "expected $bad_line bad lines, but got $bad_line_new"
17828                 return 1
17829         fi
17830
17831         if [ $expected_good -ne $good_line_new ]; then
17832                 error "expected $expected_good good lines, but got $good_line_new"
17833                 return 2
17834         fi
17835         true
17836 }
17837 run_test 170 "test lctl df to handle corrupted log ====================="
17838
17839 test_171() { # bug20592
17840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17841
17842         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17843         $LCTL set_param fail_loc=0x50e
17844         $LCTL set_param fail_val=3000
17845         multiop_bg_pause $DIR/$tfile O_s || true
17846         local MULTIPID=$!
17847         kill -USR1 $MULTIPID
17848         # cause log dump
17849         sleep 3
17850         wait $MULTIPID
17851         if dmesg | grep "recursive fault"; then
17852                 error "caught a recursive fault"
17853         fi
17854         $LCTL set_param fail_loc=0
17855         true
17856 }
17857 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17858
17859 test_172() {
17860
17861         #define OBD_FAIL_OBD_CLEANUP  0x60e
17862         $LCTL set_param fail_loc=0x60e
17863         umount $MOUNT || error "umount $MOUNT failed"
17864         stack_trap "mount_client $MOUNT"
17865
17866         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17867                 error "no client OBDs are remained"
17868
17869         $LCTL dl | while read devno state type name foo; do
17870                 case $type in
17871                 lov|osc|lmv|mdc)
17872                         $LCTL --device $name cleanup
17873                         $LCTL --device $name detach
17874                         ;;
17875                 *)
17876                         # skip server devices
17877                         ;;
17878                 esac
17879         done
17880
17881         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17882                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17883                 error "some client OBDs are still remained"
17884         fi
17885
17886 }
17887 run_test 172 "manual device removal with lctl cleanup/detach ======"
17888
17889 # it would be good to share it with obdfilter-survey/iokit-libecho code
17890 setup_obdecho_osc () {
17891         local rc=0
17892         local ost_nid=$1
17893         local obdfilter_name=$2
17894         echo "Creating new osc for $obdfilter_name on $ost_nid"
17895         # make sure we can find loopback nid
17896         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17897
17898         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17899                            ${obdfilter_name}_osc_UUID || rc=2; }
17900         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17901                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17902         return $rc
17903 }
17904
17905 cleanup_obdecho_osc () {
17906         local obdfilter_name=$1
17907         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17908         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17909         return 0
17910 }
17911
17912 obdecho_test() {
17913         local OBD=$1
17914         local node=$2
17915         local pages=${3:-64}
17916         local rc=0
17917         local id
17918
17919         local count=10
17920         local obd_size=$(get_obd_size $node $OBD)
17921         local page_size=$(get_page_size $node)
17922         if [[ -n "$obd_size" ]]; then
17923                 local new_count=$((obd_size / (pages * page_size / 1024)))
17924                 [[ $new_count -ge $count ]] || count=$new_count
17925         fi
17926
17927         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17928         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17929                            rc=2; }
17930         if [ $rc -eq 0 ]; then
17931             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17932             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17933         fi
17934         echo "New object id is $id"
17935         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17936                            rc=4; }
17937         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17938                            "test_brw $count w v $pages $id" || rc=4; }
17939         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17940                            rc=4; }
17941         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17942                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17943         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17944                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17945         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17946         return $rc
17947 }
17948
17949 test_180a() {
17950         skip "obdecho on osc is no longer supported"
17951 }
17952 run_test 180a "test obdecho on osc"
17953
17954 test_180b() {
17955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17956         remote_ost_nodsh && skip "remote OST with nodsh"
17957
17958         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17959                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17960                 error "failed to load module obdecho"
17961
17962         local target=$(do_facet ost1 $LCTL dl |
17963                        awk '/obdfilter/ { print $4; exit; }')
17964
17965         if [ -n "$target" ]; then
17966                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17967         else
17968                 do_facet ost1 $LCTL dl
17969                 error "there is no obdfilter target on ost1"
17970         fi
17971 }
17972 run_test 180b "test obdecho directly on obdfilter"
17973
17974 test_180c() { # LU-2598
17975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17976         remote_ost_nodsh && skip "remote OST with nodsh"
17977         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17978                 skip "Need MDS version at least 2.4.0"
17979
17980         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17981                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17982                 error "failed to load module obdecho"
17983
17984         local target=$(do_facet ost1 $LCTL dl |
17985                        awk '/obdfilter/ { print $4; exit; }')
17986
17987         if [ -n "$target" ]; then
17988                 local pages=16384 # 64MB bulk I/O RPC size
17989
17990                 obdecho_test "$target" ost1 "$pages" ||
17991                         error "obdecho_test with pages=$pages failed with $?"
17992         else
17993                 do_facet ost1 $LCTL dl
17994                 error "there is no obdfilter target on ost1"
17995         fi
17996 }
17997 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17998
17999 test_181() { # bug 22177
18000         test_mkdir $DIR/$tdir
18001         # create enough files to index the directory
18002         createmany -o $DIR/$tdir/foobar 4000
18003         # print attributes for debug purpose
18004         lsattr -d .
18005         # open dir
18006         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18007         MULTIPID=$!
18008         # remove the files & current working dir
18009         unlinkmany $DIR/$tdir/foobar 4000
18010         rmdir $DIR/$tdir
18011         kill -USR1 $MULTIPID
18012         wait $MULTIPID
18013         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18014         return 0
18015 }
18016 run_test 181 "Test open-unlinked dir ========================"
18017
18018 test_182a() {
18019         local fcount=1000
18020         local tcount=10
18021
18022         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18023
18024         $LCTL set_param mdc.*.rpc_stats=clear
18025
18026         for (( i = 0; i < $tcount; i++ )) ; do
18027                 mkdir $DIR/$tdir/$i
18028         done
18029
18030         for (( i = 0; i < $tcount; i++ )) ; do
18031                 createmany -o $DIR/$tdir/$i/f- $fcount &
18032         done
18033         wait
18034
18035         for (( i = 0; i < $tcount; i++ )) ; do
18036                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18037         done
18038         wait
18039
18040         $LCTL get_param mdc.*.rpc_stats
18041
18042         rm -rf $DIR/$tdir
18043 }
18044 run_test 182a "Test parallel modify metadata operations from mdc"
18045
18046 test_182b() {
18047         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18048         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18049         local dcount=1000
18050         local tcount=10
18051         local stime
18052         local etime
18053         local delta
18054
18055         do_facet mds1 $LCTL list_param \
18056                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18057                 skip "MDS lacks parallel RPC handling"
18058
18059         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18060
18061         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18062                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18063
18064         stime=$(date +%s)
18065         createmany -i 0 -d $DIR/$tdir/t- $tcount
18066
18067         for (( i = 0; i < $tcount; i++ )) ; do
18068                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18069         done
18070         wait
18071         etime=$(date +%s)
18072         delta=$((etime - stime))
18073         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18074
18075         stime=$(date +%s)
18076         for (( i = 0; i < $tcount; i++ )) ; do
18077                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18078         done
18079         wait
18080         etime=$(date +%s)
18081         delta=$((etime - stime))
18082         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18083
18084         rm -rf $DIR/$tdir
18085
18086         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18087
18088         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18089
18090         stime=$(date +%s)
18091         createmany -i 0 -d $DIR/$tdir/t- $tcount
18092
18093         for (( i = 0; i < $tcount; i++ )) ; do
18094                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18095         done
18096         wait
18097         etime=$(date +%s)
18098         delta=$((etime - stime))
18099         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18100
18101         stime=$(date +%s)
18102         for (( i = 0; i < $tcount; i++ )) ; do
18103                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18104         done
18105         wait
18106         etime=$(date +%s)
18107         delta=$((etime - stime))
18108         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18109
18110         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18111 }
18112 run_test 182b "Test parallel modify metadata operations from osp"
18113
18114 test_183() { # LU-2275
18115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18116         remote_mds_nodsh && skip "remote MDS with nodsh"
18117         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18118                 skip "Need MDS version at least 2.3.56"
18119
18120         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18121         echo aaa > $DIR/$tdir/$tfile
18122
18123 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18124         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18125
18126         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18127         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18128
18129         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18130
18131         # Flush negative dentry cache
18132         touch $DIR/$tdir/$tfile
18133
18134         # We are not checking for any leaked references here, they'll
18135         # become evident next time we do cleanup with module unload.
18136         rm -rf $DIR/$tdir
18137 }
18138 run_test 183 "No crash or request leak in case of strange dispositions ========"
18139
18140 # test suite 184 is for LU-2016, LU-2017
18141 test_184a() {
18142         check_swap_layouts_support
18143
18144         dir0=$DIR/$tdir/$testnum
18145         test_mkdir -p -c1 $dir0
18146         ref1=/etc/passwd
18147         ref2=/etc/group
18148         file1=$dir0/f1
18149         file2=$dir0/f2
18150         $LFS setstripe -c1 $file1
18151         cp $ref1 $file1
18152         $LFS setstripe -c2 $file2
18153         cp $ref2 $file2
18154         gen1=$($LFS getstripe -g $file1)
18155         gen2=$($LFS getstripe -g $file2)
18156
18157         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18158         gen=$($LFS getstripe -g $file1)
18159         [[ $gen1 != $gen ]] ||
18160                 error "Layout generation on $file1 does not change"
18161         gen=$($LFS getstripe -g $file2)
18162         [[ $gen2 != $gen ]] ||
18163                 error "Layout generation on $file2 does not change"
18164
18165         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18166         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18167
18168         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18169 }
18170 run_test 184a "Basic layout swap"
18171
18172 test_184b() {
18173         check_swap_layouts_support
18174
18175         dir0=$DIR/$tdir/$testnum
18176         mkdir -p $dir0 || error "creating dir $dir0"
18177         file1=$dir0/f1
18178         file2=$dir0/f2
18179         file3=$dir0/f3
18180         dir1=$dir0/d1
18181         dir2=$dir0/d2
18182         mkdir $dir1 $dir2
18183         $LFS setstripe -c1 $file1
18184         $LFS setstripe -c2 $file2
18185         $LFS setstripe -c1 $file3
18186         chown $RUNAS_ID $file3
18187         gen1=$($LFS getstripe -g $file1)
18188         gen2=$($LFS getstripe -g $file2)
18189
18190         $LFS swap_layouts $dir1 $dir2 &&
18191                 error "swap of directories layouts should fail"
18192         $LFS swap_layouts $dir1 $file1 &&
18193                 error "swap of directory and file layouts should fail"
18194         $RUNAS $LFS swap_layouts $file1 $file2 &&
18195                 error "swap of file we cannot write should fail"
18196         $LFS swap_layouts $file1 $file3 &&
18197                 error "swap of file with different owner should fail"
18198         /bin/true # to clear error code
18199 }
18200 run_test 184b "Forbidden layout swap (will generate errors)"
18201
18202 test_184c() {
18203         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18204         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18205         check_swap_layouts_support
18206         check_swap_layout_no_dom $DIR
18207
18208         local dir0=$DIR/$tdir/$testnum
18209         mkdir -p $dir0 || error "creating dir $dir0"
18210
18211         local ref1=$dir0/ref1
18212         local ref2=$dir0/ref2
18213         local file1=$dir0/file1
18214         local file2=$dir0/file2
18215         # create a file large enough for the concurrent test
18216         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18217         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18218         echo "ref file size: ref1($(stat -c %s $ref1))," \
18219              "ref2($(stat -c %s $ref2))"
18220
18221         cp $ref2 $file2
18222         dd if=$ref1 of=$file1 bs=16k &
18223         local DD_PID=$!
18224
18225         # Make sure dd starts to copy file, but wait at most 5 seconds
18226         local loops=0
18227         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18228
18229         $LFS swap_layouts $file1 $file2
18230         local rc=$?
18231         wait $DD_PID
18232         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18233         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18234
18235         # how many bytes copied before swapping layout
18236         local copied=$(stat -c %s $file2)
18237         local remaining=$(stat -c %s $ref1)
18238         remaining=$((remaining - copied))
18239         echo "Copied $copied bytes before swapping layout..."
18240
18241         cmp -n $copied $file1 $ref2 | grep differ &&
18242                 error "Content mismatch [0, $copied) of ref2 and file1"
18243         cmp -n $copied $file2 $ref1 ||
18244                 error "Content mismatch [0, $copied) of ref1 and file2"
18245         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18246                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18247
18248         # clean up
18249         rm -f $ref1 $ref2 $file1 $file2
18250 }
18251 run_test 184c "Concurrent write and layout swap"
18252
18253 test_184d() {
18254         check_swap_layouts_support
18255         check_swap_layout_no_dom $DIR
18256         [ -z "$(which getfattr 2>/dev/null)" ] &&
18257                 skip_env "no getfattr command"
18258
18259         local file1=$DIR/$tdir/$tfile-1
18260         local file2=$DIR/$tdir/$tfile-2
18261         local file3=$DIR/$tdir/$tfile-3
18262         local lovea1
18263         local lovea2
18264
18265         mkdir -p $DIR/$tdir
18266         touch $file1 || error "create $file1 failed"
18267         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18268                 error "create $file2 failed"
18269         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18270                 error "create $file3 failed"
18271         lovea1=$(get_layout_param $file1)
18272
18273         $LFS swap_layouts $file2 $file3 ||
18274                 error "swap $file2 $file3 layouts failed"
18275         $LFS swap_layouts $file1 $file2 ||
18276                 error "swap $file1 $file2 layouts failed"
18277
18278         lovea2=$(get_layout_param $file2)
18279         echo "$lovea1"
18280         echo "$lovea2"
18281         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18282
18283         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18284         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18285 }
18286 run_test 184d "allow stripeless layouts swap"
18287
18288 test_184e() {
18289         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18290                 skip "Need MDS version at least 2.6.94"
18291         check_swap_layouts_support
18292         check_swap_layout_no_dom $DIR
18293         [ -z "$(which getfattr 2>/dev/null)" ] &&
18294                 skip_env "no getfattr command"
18295
18296         local file1=$DIR/$tdir/$tfile-1
18297         local file2=$DIR/$tdir/$tfile-2
18298         local file3=$DIR/$tdir/$tfile-3
18299         local lovea
18300
18301         mkdir -p $DIR/$tdir
18302         touch $file1 || error "create $file1 failed"
18303         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18304                 error "create $file2 failed"
18305         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18306                 error "create $file3 failed"
18307
18308         $LFS swap_layouts $file1 $file2 ||
18309                 error "swap $file1 $file2 layouts failed"
18310
18311         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18312         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18313
18314         echo 123 > $file1 || error "Should be able to write into $file1"
18315
18316         $LFS swap_layouts $file1 $file3 ||
18317                 error "swap $file1 $file3 layouts failed"
18318
18319         echo 123 > $file1 || error "Should be able to write into $file1"
18320
18321         rm -rf $file1 $file2 $file3
18322 }
18323 run_test 184e "Recreate layout after stripeless layout swaps"
18324
18325 test_184f() {
18326         # Create a file with name longer than sizeof(struct stat) ==
18327         # 144 to see if we can get chars from the file name to appear
18328         # in the returned striping. Note that 'f' == 0x66.
18329         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18330
18331         mkdir -p $DIR/$tdir
18332         mcreate $DIR/$tdir/$file
18333         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18334                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18335         fi
18336 }
18337 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18338
18339 test_185() { # LU-2441
18340         # LU-3553 - no volatile file support in old servers
18341         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18342                 skip "Need MDS version at least 2.3.60"
18343
18344         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18345         touch $DIR/$tdir/spoo
18346         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18347         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18348                 error "cannot create/write a volatile file"
18349         [ "$FILESET" == "" ] &&
18350         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18351                 error "FID is still valid after close"
18352
18353         multiop_bg_pause $DIR/$tdir vVw4096_c
18354         local multi_pid=$!
18355
18356         local OLD_IFS=$IFS
18357         IFS=":"
18358         local fidv=($fid)
18359         IFS=$OLD_IFS
18360         # assume that the next FID for this client is sequential, since stdout
18361         # is unfortunately eaten by multiop_bg_pause
18362         local n=$((${fidv[1]} + 1))
18363         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18364         if [ "$FILESET" == "" ]; then
18365                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18366                         error "FID is missing before close"
18367         fi
18368         kill -USR1 $multi_pid
18369         # 1 second delay, so if mtime change we will see it
18370         sleep 1
18371         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18372         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18373 }
18374 run_test 185 "Volatile file support"
18375
18376 function create_check_volatile() {
18377         local idx=$1
18378         local tgt
18379
18380         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18381         local PID=$!
18382         sleep 1
18383         local FID=$(cat /tmp/${tfile}.fid)
18384         [ "$FID" == "" ] && error "can't get FID for volatile"
18385         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18386         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18387         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18388         kill -USR1 $PID
18389         wait
18390         sleep 1
18391         cancel_lru_locks mdc # flush opencache
18392         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18393         return 0
18394 }
18395
18396 test_185a(){
18397         # LU-12516 - volatile creation via .lustre
18398         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18399                 skip "Need MDS version at least 2.3.55"
18400
18401         create_check_volatile 0
18402         [ $MDSCOUNT -lt 2 ] && return 0
18403
18404         # DNE case
18405         create_check_volatile 1
18406
18407         return 0
18408 }
18409 run_test 185a "Volatile file creation in .lustre/fid/"
18410
18411 test_187a() {
18412         remote_mds_nodsh && skip "remote MDS with nodsh"
18413         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18414                 skip "Need MDS version at least 2.3.0"
18415
18416         local dir0=$DIR/$tdir/$testnum
18417         mkdir -p $dir0 || error "creating dir $dir0"
18418
18419         local file=$dir0/file1
18420         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18421         local dv1=$($LFS data_version $file)
18422         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18423         local dv2=$($LFS data_version $file)
18424         [[ $dv1 != $dv2 ]] ||
18425                 error "data version did not change on write $dv1 == $dv2"
18426
18427         # clean up
18428         rm -f $file1
18429 }
18430 run_test 187a "Test data version change"
18431
18432 test_187b() {
18433         remote_mds_nodsh && skip "remote MDS with nodsh"
18434         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18435                 skip "Need MDS version at least 2.3.0"
18436
18437         local dir0=$DIR/$tdir/$testnum
18438         mkdir -p $dir0 || error "creating dir $dir0"
18439
18440         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18441         [[ ${DV[0]} != ${DV[1]} ]] ||
18442                 error "data version did not change on write"\
18443                       " ${DV[0]} == ${DV[1]}"
18444
18445         # clean up
18446         rm -f $file1
18447 }
18448 run_test 187b "Test data version change on volatile file"
18449
18450 test_200() {
18451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18452         remote_mgs_nodsh && skip "remote MGS with nodsh"
18453         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18454
18455         local POOL=${POOL:-cea1}
18456         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18457         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18458         # Pool OST targets
18459         local first_ost=0
18460         local last_ost=$(($OSTCOUNT - 1))
18461         local ost_step=2
18462         local ost_list=$(seq $first_ost $ost_step $last_ost)
18463         local ost_range="$first_ost $last_ost $ost_step"
18464         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18465         local file_dir=$POOL_ROOT/file_tst
18466         local subdir=$test_path/subdir
18467         local rc=0
18468
18469         while : ; do
18470                 # former test_200a test_200b
18471                 pool_add $POOL                          || { rc=$? ; break; }
18472                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18473                 # former test_200c test_200d
18474                 mkdir -p $test_path
18475                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18476                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18477                 mkdir -p $subdir
18478                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18479                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18480                                                         || { rc=$? ; break; }
18481                 # former test_200e test_200f
18482                 local files=$((OSTCOUNT*3))
18483                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18484                                                         || { rc=$? ; break; }
18485                 pool_create_files $POOL $file_dir $files "$ost_list" \
18486                                                         || { rc=$? ; break; }
18487                 # former test_200g test_200h
18488                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18489                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18490
18491                 # former test_201a test_201b test_201c
18492                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18493
18494                 local f=$test_path/$tfile
18495                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18496                 pool_remove $POOL $f                    || { rc=$? ; break; }
18497                 break
18498         done
18499
18500         destroy_test_pools
18501
18502         return $rc
18503 }
18504 run_test 200 "OST pools"
18505
18506 # usage: default_attr <count | size | offset>
18507 default_attr() {
18508         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18509 }
18510
18511 # usage: check_default_stripe_attr
18512 check_default_stripe_attr() {
18513         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18514         case $1 in
18515         --stripe-count|-c)
18516                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18517         --stripe-size|-S)
18518                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18519         --stripe-index|-i)
18520                 EXPECTED=-1;;
18521         *)
18522                 error "unknown getstripe attr '$1'"
18523         esac
18524
18525         [ $ACTUAL == $EXPECTED ] ||
18526                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18527 }
18528
18529 test_204a() {
18530         test_mkdir $DIR/$tdir
18531         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18532
18533         check_default_stripe_attr --stripe-count
18534         check_default_stripe_attr --stripe-size
18535         check_default_stripe_attr --stripe-index
18536 }
18537 run_test 204a "Print default stripe attributes"
18538
18539 test_204b() {
18540         test_mkdir $DIR/$tdir
18541         $LFS setstripe --stripe-count 1 $DIR/$tdir
18542
18543         check_default_stripe_attr --stripe-size
18544         check_default_stripe_attr --stripe-index
18545 }
18546 run_test 204b "Print default stripe size and offset"
18547
18548 test_204c() {
18549         test_mkdir $DIR/$tdir
18550         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18551
18552         check_default_stripe_attr --stripe-count
18553         check_default_stripe_attr --stripe-index
18554 }
18555 run_test 204c "Print default stripe count and offset"
18556
18557 test_204d() {
18558         test_mkdir $DIR/$tdir
18559         $LFS setstripe --stripe-index 0 $DIR/$tdir
18560
18561         check_default_stripe_attr --stripe-count
18562         check_default_stripe_attr --stripe-size
18563 }
18564 run_test 204d "Print default stripe count and size"
18565
18566 test_204e() {
18567         test_mkdir $DIR/$tdir
18568         $LFS setstripe -d $DIR/$tdir
18569
18570         check_default_stripe_attr --stripe-count --raw
18571         check_default_stripe_attr --stripe-size --raw
18572         check_default_stripe_attr --stripe-index --raw
18573 }
18574 run_test 204e "Print raw stripe attributes"
18575
18576 test_204f() {
18577         test_mkdir $DIR/$tdir
18578         $LFS setstripe --stripe-count 1 $DIR/$tdir
18579
18580         check_default_stripe_attr --stripe-size --raw
18581         check_default_stripe_attr --stripe-index --raw
18582 }
18583 run_test 204f "Print raw stripe size and offset"
18584
18585 test_204g() {
18586         test_mkdir $DIR/$tdir
18587         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18588
18589         check_default_stripe_attr --stripe-count --raw
18590         check_default_stripe_attr --stripe-index --raw
18591 }
18592 run_test 204g "Print raw stripe count and offset"
18593
18594 test_204h() {
18595         test_mkdir $DIR/$tdir
18596         $LFS setstripe --stripe-index 0 $DIR/$tdir
18597
18598         check_default_stripe_attr --stripe-count --raw
18599         check_default_stripe_attr --stripe-size --raw
18600 }
18601 run_test 204h "Print raw stripe count and size"
18602
18603 # Figure out which job scheduler is being used, if any,
18604 # or use a fake one
18605 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18606         JOBENV=SLURM_JOB_ID
18607 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18608         JOBENV=LSB_JOBID
18609 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18610         JOBENV=PBS_JOBID
18611 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18612         JOBENV=LOADL_STEP_ID
18613 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18614         JOBENV=JOB_ID
18615 else
18616         $LCTL list_param jobid_name > /dev/null 2>&1
18617         if [ $? -eq 0 ]; then
18618                 JOBENV=nodelocal
18619         else
18620                 JOBENV=FAKE_JOBID
18621         fi
18622 fi
18623 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18624
18625 verify_jobstats() {
18626         local cmd=($1)
18627         shift
18628         local facets="$@"
18629
18630 # we don't really need to clear the stats for this test to work, since each
18631 # command has a unique jobid, but it makes debugging easier if needed.
18632 #       for facet in $facets; do
18633 #               local dev=$(convert_facet2label $facet)
18634 #               # clear old jobstats
18635 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18636 #       done
18637
18638         # use a new JobID for each test, or we might see an old one
18639         [ "$JOBENV" = "FAKE_JOBID" ] &&
18640                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18641
18642         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18643
18644         [ "$JOBENV" = "nodelocal" ] && {
18645                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18646                 $LCTL set_param jobid_name=$FAKE_JOBID
18647                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18648         }
18649
18650         log "Test: ${cmd[*]}"
18651         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18652
18653         if [ $JOBENV = "FAKE_JOBID" ]; then
18654                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18655         else
18656                 ${cmd[*]}
18657         fi
18658
18659         # all files are created on OST0000
18660         for facet in $facets; do
18661                 local stats="*.$(convert_facet2label $facet).job_stats"
18662
18663                 # strip out libtool wrappers for in-tree executables
18664                 if (( $(do_facet $facet lctl get_param $stats |
18665                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18666                         do_facet $facet lctl get_param $stats
18667                         error "No jobstats for $JOBVAL found on $facet::$stats"
18668                 fi
18669         done
18670 }
18671
18672 jobstats_set() {
18673         local new_jobenv=$1
18674
18675         set_persistent_param_and_check client "jobid_var" \
18676                 "$FSNAME.sys.jobid_var" $new_jobenv
18677 }
18678
18679 test_205a() { # Job stats
18680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18681         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18682                 skip "Need MDS version with at least 2.7.1"
18683         remote_mgs_nodsh && skip "remote MGS with nodsh"
18684         remote_mds_nodsh && skip "remote MDS with nodsh"
18685         remote_ost_nodsh && skip "remote OST with nodsh"
18686         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18687                 skip "Server doesn't support jobstats"
18688         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18689
18690         local old_jobenv=$($LCTL get_param -n jobid_var)
18691         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18692
18693         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18694                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18695         else
18696                 stack_trap "do_facet mgs $PERM_CMD \
18697                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18698         fi
18699         changelog_register
18700
18701         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18702                                 mdt.*.job_cleanup_interval | head -n 1)
18703         local new_interval=5
18704         do_facet $SINGLEMDS \
18705                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18706         stack_trap "do_facet $SINGLEMDS \
18707                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18708         local start=$SECONDS
18709
18710         local cmd
18711         # mkdir
18712         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18713         verify_jobstats "$cmd" "$SINGLEMDS"
18714         # rmdir
18715         cmd="rmdir $DIR/$tdir"
18716         verify_jobstats "$cmd" "$SINGLEMDS"
18717         # mkdir on secondary MDT
18718         if [ $MDSCOUNT -gt 1 ]; then
18719                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18720                 verify_jobstats "$cmd" "mds2"
18721         fi
18722         # mknod
18723         cmd="mknod $DIR/$tfile c 1 3"
18724         verify_jobstats "$cmd" "$SINGLEMDS"
18725         # unlink
18726         cmd="rm -f $DIR/$tfile"
18727         verify_jobstats "$cmd" "$SINGLEMDS"
18728         # create all files on OST0000 so verify_jobstats can find OST stats
18729         # open & close
18730         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18731         verify_jobstats "$cmd" "$SINGLEMDS"
18732         # setattr
18733         cmd="touch $DIR/$tfile"
18734         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18735         # write
18736         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18737         verify_jobstats "$cmd" "ost1"
18738         # read
18739         cancel_lru_locks osc
18740         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18741         verify_jobstats "$cmd" "ost1"
18742         # truncate
18743         cmd="$TRUNCATE $DIR/$tfile 0"
18744         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18745         # rename
18746         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18747         verify_jobstats "$cmd" "$SINGLEMDS"
18748         # jobstats expiry - sleep until old stats should be expired
18749         local left=$((new_interval + 5 - (SECONDS - start)))
18750         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18751                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18752                         "0" $left
18753         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18754         verify_jobstats "$cmd" "$SINGLEMDS"
18755         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18756             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18757
18758         # Ensure that jobid are present in changelog (if supported by MDS)
18759         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18760                 changelog_dump | tail -10
18761                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18762                 [ $jobids -eq 9 ] ||
18763                         error "Wrong changelog jobid count $jobids != 9"
18764
18765                 # LU-5862
18766                 JOBENV="disable"
18767                 jobstats_set $JOBENV
18768                 touch $DIR/$tfile
18769                 changelog_dump | grep $tfile
18770                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18771                 [ $jobids -eq 0 ] ||
18772                         error "Unexpected jobids when jobid_var=$JOBENV"
18773         fi
18774
18775         # test '%j' access to environment variable - if supported
18776         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18777                 JOBENV="JOBCOMPLEX"
18778                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18779
18780                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18781         fi
18782
18783         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18784                 JOBENV="JOBCOMPLEX"
18785                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18786
18787                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18788         fi
18789
18790         # test '%j' access to per-session jobid - if supported
18791         if lctl list_param jobid_this_session > /dev/null 2>&1
18792         then
18793                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18794                 lctl set_param jobid_this_session=$USER
18795
18796                 JOBENV="JOBCOMPLEX"
18797                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18798
18799                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18800         fi
18801 }
18802 run_test 205a "Verify job stats"
18803
18804 # LU-13117, LU-13597
18805 test_205b() {
18806         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18807                 skip "Need MDS version at least 2.13.54.91"
18808
18809         local job_stats="mdt.*.job_stats"
18810         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
18811
18812         do_facet mds1 $LCTL set_param $job_stats=clear
18813
18814         # Setting jobid_var to USER might not be supported
18815         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
18816         $LCTL set_param jobid_var=USER || true
18817         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
18818         $LCTL set_param jobid_name="%j.%e.%u"
18819
18820         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18821         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
18822                 { do_facet mds1 $LCTL get_param $job_stats;
18823                   error "Unexpected jobid found"; }
18824         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
18825                 { do_facet mds1 $LCTL get_param $job_stats;
18826                   error "wrong job_stats format found"; }
18827
18828         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
18829                 echo "MDS does not yet escape jobid" && return 0
18830         $LCTL set_param jobid_var=TEST205b
18831         env -i TEST205b="has sp" touch $DIR/$tfile.2
18832         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
18833                 { do_facet mds1 $LCTL get_param $job_stats;
18834                   error "jobid not escaped"; }
18835 }
18836 run_test 205b "Verify job stats jobid and output format"
18837
18838 # LU-13733
18839 test_205c() {
18840         $LCTL set_param llite.*.stats=0
18841         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18842         $LCTL get_param llite.*.stats
18843         $LCTL get_param llite.*.stats | grep \
18844                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18845                         error "wrong client stats format found"
18846 }
18847 run_test 205c "Verify client stats format"
18848
18849 # LU-1480, LU-1773 and LU-1657
18850 test_206() {
18851         mkdir -p $DIR/$tdir
18852         $LFS setstripe -c -1 $DIR/$tdir
18853 #define OBD_FAIL_LOV_INIT 0x1403
18854         $LCTL set_param fail_loc=0xa0001403
18855         $LCTL set_param fail_val=1
18856         touch $DIR/$tdir/$tfile || true
18857 }
18858 run_test 206 "fail lov_init_raid0() doesn't lbug"
18859
18860 test_207a() {
18861         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18862         local fsz=`stat -c %s $DIR/$tfile`
18863         cancel_lru_locks mdc
18864
18865         # do not return layout in getattr intent
18866 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18867         $LCTL set_param fail_loc=0x170
18868         local sz=`stat -c %s $DIR/$tfile`
18869
18870         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18871
18872         rm -rf $DIR/$tfile
18873 }
18874 run_test 207a "can refresh layout at glimpse"
18875
18876 test_207b() {
18877         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18878         local cksum=`md5sum $DIR/$tfile`
18879         local fsz=`stat -c %s $DIR/$tfile`
18880         cancel_lru_locks mdc
18881         cancel_lru_locks osc
18882
18883         # do not return layout in getattr intent
18884 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18885         $LCTL set_param fail_loc=0x171
18886
18887         # it will refresh layout after the file is opened but before read issues
18888         echo checksum is "$cksum"
18889         echo "$cksum" |md5sum -c --quiet || error "file differs"
18890
18891         rm -rf $DIR/$tfile
18892 }
18893 run_test 207b "can refresh layout at open"
18894
18895 test_208() {
18896         # FIXME: in this test suite, only RD lease is used. This is okay
18897         # for now as only exclusive open is supported. After generic lease
18898         # is done, this test suite should be revised. - Jinshan
18899
18900         remote_mds_nodsh && skip "remote MDS with nodsh"
18901         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18902                 skip "Need MDS version at least 2.4.52"
18903
18904         echo "==== test 1: verify get lease work"
18905         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18906
18907         echo "==== test 2: verify lease can be broken by upcoming open"
18908         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18909         local PID=$!
18910         sleep 2
18911
18912         $MULTIOP $DIR/$tfile oO_RDWR:c
18913         kill -USR1 $PID && wait $PID || error "break lease error"
18914
18915         echo "==== test 3: verify lease can't be granted if an open already exists"
18916         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18917         local PID=$!
18918         sleep 2
18919
18920         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18921         kill -USR1 $PID && wait $PID || error "open file error"
18922
18923         echo "==== test 4: lease can sustain over recovery"
18924         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18925         PID=$!
18926         sleep 2
18927
18928         fail mds1
18929
18930         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18931
18932         echo "==== test 5: lease broken can't be regained by replay"
18933         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18934         PID=$!
18935         sleep 2
18936
18937         # open file to break lease and then recovery
18938         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18939         fail mds1
18940
18941         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18942
18943         rm -f $DIR/$tfile
18944 }
18945 run_test 208 "Exclusive open"
18946
18947 test_209() {
18948         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18949                 skip_env "must have disp_stripe"
18950
18951         touch $DIR/$tfile
18952         sync; sleep 5; sync;
18953
18954         echo 3 > /proc/sys/vm/drop_caches
18955         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18956                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18957         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18958
18959         # open/close 500 times
18960         for i in $(seq 500); do
18961                 cat $DIR/$tfile
18962         done
18963
18964         echo 3 > /proc/sys/vm/drop_caches
18965         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18966                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18967         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18968
18969         echo "before: $req_before, after: $req_after"
18970         [ $((req_after - req_before)) -ge 300 ] &&
18971                 error "open/close requests are not freed"
18972         return 0
18973 }
18974 run_test 209 "read-only open/close requests should be freed promptly"
18975
18976 test_210() {
18977         local pid
18978
18979         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18980         pid=$!
18981         sleep 1
18982
18983         $LFS getstripe $DIR/$tfile
18984         kill -USR1 $pid
18985         wait $pid || error "multiop failed"
18986
18987         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18988         pid=$!
18989         sleep 1
18990
18991         $LFS getstripe $DIR/$tfile
18992         kill -USR1 $pid
18993         wait $pid || error "multiop failed"
18994 }
18995 run_test 210 "lfs getstripe does not break leases"
18996
18997 test_212() {
18998         size=`date +%s`
18999         size=$((size % 8192 + 1))
19000         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19001         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19002         rm -f $DIR/f212 $DIR/f212.xyz
19003 }
19004 run_test 212 "Sendfile test ============================================"
19005
19006 test_213() {
19007         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19008         cancel_lru_locks osc
19009         lctl set_param fail_loc=0x8000040f
19010         # generate a read lock
19011         cat $DIR/$tfile > /dev/null
19012         # write to the file, it will try to cancel the above read lock.
19013         cat /etc/hosts >> $DIR/$tfile
19014 }
19015 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19016
19017 test_214() { # for bug 20133
19018         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19019         for (( i=0; i < 340; i++ )) ; do
19020                 touch $DIR/$tdir/d214c/a$i
19021         done
19022
19023         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19024         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19025         ls $DIR/d214c || error "ls $DIR/d214c failed"
19026         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19027         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19028 }
19029 run_test 214 "hash-indexed directory test - bug 20133"
19030
19031 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19032 create_lnet_proc_files() {
19033         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19034 }
19035
19036 # counterpart of create_lnet_proc_files
19037 remove_lnet_proc_files() {
19038         rm -f $TMP/lnet_$1.sys
19039 }
19040
19041 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19042 # 3rd arg as regexp for body
19043 check_lnet_proc_stats() {
19044         local l=$(cat "$TMP/lnet_$1" |wc -l)
19045         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19046
19047         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19048 }
19049
19050 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19051 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19052 # optional and can be regexp for 2nd line (lnet.routes case)
19053 check_lnet_proc_entry() {
19054         local blp=2          # blp stands for 'position of 1st line of body'
19055         [ -z "$5" ] || blp=3 # lnet.routes case
19056
19057         local l=$(cat "$TMP/lnet_$1" |wc -l)
19058         # subtracting one from $blp because the body can be empty
19059         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19060
19061         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19062                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19063
19064         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19065                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19066
19067         # bail out if any unexpected line happened
19068         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19069         [ "$?" != 0 ] || error "$2 misformatted"
19070 }
19071
19072 test_215() { # for bugs 18102, 21079, 21517
19073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19074
19075         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19076         local P='[1-9][0-9]*'           # positive numeric
19077         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19078         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19079         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19080         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19081
19082         local L1 # regexp for 1st line
19083         local L2 # regexp for 2nd line (optional)
19084         local BR # regexp for the rest (body)
19085
19086         # lnet.stats should look as 11 space-separated non-negative numerics
19087         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19088         create_lnet_proc_files "stats"
19089         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19090         remove_lnet_proc_files "stats"
19091
19092         # lnet.routes should look like this:
19093         # Routing disabled/enabled
19094         # net hops priority state router
19095         # where net is a string like tcp0, hops > 0, priority >= 0,
19096         # state is up/down,
19097         # router is a string like 192.168.1.1@tcp2
19098         L1="^Routing (disabled|enabled)$"
19099         L2="^net +hops +priority +state +router$"
19100         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19101         create_lnet_proc_files "routes"
19102         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19103         remove_lnet_proc_files "routes"
19104
19105         # lnet.routers should look like this:
19106         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19107         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19108         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19109         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19110         L1="^ref +rtr_ref +alive +router$"
19111         BR="^$P +$P +(up|down) +$NID$"
19112         create_lnet_proc_files "routers"
19113         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19114         remove_lnet_proc_files "routers"
19115
19116         # lnet.peers should look like this:
19117         # nid refs state last max rtr min tx min queue
19118         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19119         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19120         # numeric (0 or >0 or <0), queue >= 0.
19121         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19122         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19123         create_lnet_proc_files "peers"
19124         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19125         remove_lnet_proc_files "peers"
19126
19127         # lnet.buffers  should look like this:
19128         # pages count credits min
19129         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19130         L1="^pages +count +credits +min$"
19131         BR="^ +$N +$N +$I +$I$"
19132         create_lnet_proc_files "buffers"
19133         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19134         remove_lnet_proc_files "buffers"
19135
19136         # lnet.nis should look like this:
19137         # nid status alive refs peer rtr max tx min
19138         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19139         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19140         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19141         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19142         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19143         create_lnet_proc_files "nis"
19144         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19145         remove_lnet_proc_files "nis"
19146
19147         # can we successfully write to lnet.stats?
19148         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19149 }
19150 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19151
19152 test_216() { # bug 20317
19153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19154         remote_ost_nodsh && skip "remote OST with nodsh"
19155
19156         local node
19157         local facets=$(get_facets OST)
19158         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19159
19160         save_lustre_params client "osc.*.contention_seconds" > $p
19161         save_lustre_params $facets \
19162                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19163         save_lustre_params $facets \
19164                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19165         save_lustre_params $facets \
19166                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19167         clear_stats osc.*.osc_stats
19168
19169         # agressive lockless i/o settings
19170         do_nodes $(comma_list $(osts_nodes)) \
19171                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19172                         ldlm.namespaces.filter-*.contended_locks=0 \
19173                         ldlm.namespaces.filter-*.contention_seconds=60"
19174         lctl set_param -n osc.*.contention_seconds=60
19175
19176         $DIRECTIO write $DIR/$tfile 0 10 4096
19177         $CHECKSTAT -s 40960 $DIR/$tfile
19178
19179         # disable lockless i/o
19180         do_nodes $(comma_list $(osts_nodes)) \
19181                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19182                         ldlm.namespaces.filter-*.contended_locks=32 \
19183                         ldlm.namespaces.filter-*.contention_seconds=0"
19184         lctl set_param -n osc.*.contention_seconds=0
19185         clear_stats osc.*.osc_stats
19186
19187         dd if=/dev/zero of=$DIR/$tfile count=0
19188         $CHECKSTAT -s 0 $DIR/$tfile
19189
19190         restore_lustre_params <$p
19191         rm -f $p
19192         rm $DIR/$tfile
19193 }
19194 run_test 216 "check lockless direct write updates file size and kms correctly"
19195
19196 test_217() { # bug 22430
19197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19198
19199         local node
19200         local nid
19201
19202         for node in $(nodes_list); do
19203                 nid=$(host_nids_address $node $NETTYPE)
19204                 if [[ $nid = *-* ]] ; then
19205                         echo "lctl ping $(h2nettype $nid)"
19206                         lctl ping $(h2nettype $nid)
19207                 else
19208                         echo "skipping $node (no hyphen detected)"
19209                 fi
19210         done
19211 }
19212 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19213
19214 test_218() {
19215        # do directio so as not to populate the page cache
19216        log "creating a 10 Mb file"
19217        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19218        log "starting reads"
19219        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19220        log "truncating the file"
19221        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19222        log "killing dd"
19223        kill %+ || true # reads might have finished
19224        echo "wait until dd is finished"
19225        wait
19226        log "removing the temporary file"
19227        rm -rf $DIR/$tfile || error "tmp file removal failed"
19228 }
19229 run_test 218 "parallel read and truncate should not deadlock"
19230
19231 test_219() {
19232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19233
19234         # write one partial page
19235         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19236         # set no grant so vvp_io_commit_write will do sync write
19237         $LCTL set_param fail_loc=0x411
19238         # write a full page at the end of file
19239         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19240
19241         $LCTL set_param fail_loc=0
19242         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19243         $LCTL set_param fail_loc=0x411
19244         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19245
19246         # LU-4201
19247         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19248         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19249 }
19250 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19251
19252 test_220() { #LU-325
19253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19254         remote_ost_nodsh && skip "remote OST with nodsh"
19255         remote_mds_nodsh && skip "remote MDS with nodsh"
19256         remote_mgs_nodsh && skip "remote MGS with nodsh"
19257
19258         local OSTIDX=0
19259
19260         # create on MDT0000 so the last_id and next_id are correct
19261         mkdir_on_mdt0 $DIR/$tdir
19262         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19263         OST=${OST%_UUID}
19264
19265         # on the mdt's osc
19266         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19267         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19268                         osp.$mdtosc_proc1.prealloc_last_id)
19269         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19270                         osp.$mdtosc_proc1.prealloc_next_id)
19271
19272         $LFS df -i
19273
19274         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19275         #define OBD_FAIL_OST_ENOINO              0x229
19276         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19277         create_pool $FSNAME.$TESTNAME || return 1
19278         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19279
19280         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19281
19282         MDSOBJS=$((last_id - next_id))
19283         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19284
19285         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19286         echo "OST still has $count kbytes free"
19287
19288         echo "create $MDSOBJS files @next_id..."
19289         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19290
19291         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19292                         osp.$mdtosc_proc1.prealloc_last_id)
19293         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19294                         osp.$mdtosc_proc1.prealloc_next_id)
19295
19296         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19297         $LFS df -i
19298
19299         echo "cleanup..."
19300
19301         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19302         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19303
19304         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19305                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19306         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19307                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19308         echo "unlink $MDSOBJS files @$next_id..."
19309         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19310 }
19311 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19312
19313 test_221() {
19314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19315
19316         dd if=`which date` of=$MOUNT/date oflag=sync
19317         chmod +x $MOUNT/date
19318
19319         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19320         $LCTL set_param fail_loc=0x80001401
19321
19322         $MOUNT/date > /dev/null
19323         rm -f $MOUNT/date
19324 }
19325 run_test 221 "make sure fault and truncate race to not cause OOM"
19326
19327 test_222a () {
19328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19329
19330         rm -rf $DIR/$tdir
19331         test_mkdir $DIR/$tdir
19332         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19333         createmany -o $DIR/$tdir/$tfile 10
19334         cancel_lru_locks mdc
19335         cancel_lru_locks osc
19336         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19337         $LCTL set_param fail_loc=0x31a
19338         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19339         $LCTL set_param fail_loc=0
19340         rm -r $DIR/$tdir
19341 }
19342 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19343
19344 test_222b () {
19345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19346
19347         rm -rf $DIR/$tdir
19348         test_mkdir $DIR/$tdir
19349         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19350         createmany -o $DIR/$tdir/$tfile 10
19351         cancel_lru_locks mdc
19352         cancel_lru_locks osc
19353         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19354         $LCTL set_param fail_loc=0x31a
19355         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19356         $LCTL set_param fail_loc=0
19357 }
19358 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19359
19360 test_223 () {
19361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19362
19363         rm -rf $DIR/$tdir
19364         test_mkdir $DIR/$tdir
19365         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19366         createmany -o $DIR/$tdir/$tfile 10
19367         cancel_lru_locks mdc
19368         cancel_lru_locks osc
19369         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19370         $LCTL set_param fail_loc=0x31b
19371         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19372         $LCTL set_param fail_loc=0
19373         rm -r $DIR/$tdir
19374 }
19375 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19376
19377 test_224a() { # LU-1039, MRP-303
19378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19379         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19380         $LCTL set_param fail_loc=0x508
19381         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19382         $LCTL set_param fail_loc=0
19383         df $DIR
19384 }
19385 run_test 224a "Don't panic on bulk IO failure"
19386
19387 test_224bd_sub() { # LU-1039, MRP-303
19388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19389         local timeout=$1
19390
19391         shift
19392         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19393
19394         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19395
19396         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19397         cancel_lru_locks osc
19398         set_checksums 0
19399         stack_trap "set_checksums $ORIG_CSUM" EXIT
19400         local at_max_saved=0
19401
19402         # adaptive timeouts may prevent seeing the issue
19403         if at_is_enabled; then
19404                 at_max_saved=$(at_max_get mds)
19405                 at_max_set 0 mds client
19406                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19407         fi
19408
19409         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19410         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19411         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19412
19413         do_facet ost1 $LCTL set_param fail_loc=0
19414         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19415         df $DIR
19416 }
19417
19418 test_224b() {
19419         test_224bd_sub 3 error "dd failed"
19420 }
19421 run_test 224b "Don't panic on bulk IO failure"
19422
19423 test_224c() { # LU-6441
19424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19425         remote_mds_nodsh && skip "remote MDS with nodsh"
19426
19427         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19428         save_writethrough $p
19429         set_cache writethrough on
19430
19431         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19432         local at_max=$($LCTL get_param -n at_max)
19433         local timeout=$($LCTL get_param -n timeout)
19434         local test_at="at_max"
19435         local param_at="$FSNAME.sys.at_max"
19436         local test_timeout="timeout"
19437         local param_timeout="$FSNAME.sys.timeout"
19438
19439         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19440
19441         set_persistent_param_and_check client "$test_at" "$param_at" 0
19442         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19443
19444         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19445         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19446         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19447         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19448         sync
19449         do_facet ost1 "$LCTL set_param fail_loc=0"
19450
19451         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19452         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19453                 $timeout
19454
19455         $LCTL set_param -n $pages_per_rpc
19456         restore_lustre_params < $p
19457         rm -f $p
19458 }
19459 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19460
19461 test_224d() { # LU-11169
19462         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19463 }
19464 run_test 224d "Don't corrupt data on bulk IO timeout"
19465
19466 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19467 test_225a () {
19468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19469         if [ -z ${MDSSURVEY} ]; then
19470                 skip_env "mds-survey not found"
19471         fi
19472         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19473                 skip "Need MDS version at least 2.2.51"
19474
19475         local mds=$(facet_host $SINGLEMDS)
19476         local target=$(do_nodes $mds 'lctl dl' |
19477                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19478
19479         local cmd1="file_count=1000 thrhi=4"
19480         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19481         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19482         local cmd="$cmd1 $cmd2 $cmd3"
19483
19484         rm -f ${TMP}/mds_survey*
19485         echo + $cmd
19486         eval $cmd || error "mds-survey with zero-stripe failed"
19487         cat ${TMP}/mds_survey*
19488         rm -f ${TMP}/mds_survey*
19489 }
19490 run_test 225a "Metadata survey sanity with zero-stripe"
19491
19492 test_225b () {
19493         if [ -z ${MDSSURVEY} ]; then
19494                 skip_env "mds-survey not found"
19495         fi
19496         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19497                 skip "Need MDS version at least 2.2.51"
19498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19499         remote_mds_nodsh && skip "remote MDS with nodsh"
19500         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19501                 skip_env "Need to mount OST to test"
19502         fi
19503
19504         local mds=$(facet_host $SINGLEMDS)
19505         local target=$(do_nodes $mds 'lctl dl' |
19506                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19507
19508         local cmd1="file_count=1000 thrhi=4"
19509         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19510         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19511         local cmd="$cmd1 $cmd2 $cmd3"
19512
19513         rm -f ${TMP}/mds_survey*
19514         echo + $cmd
19515         eval $cmd || error "mds-survey with stripe_count failed"
19516         cat ${TMP}/mds_survey*
19517         rm -f ${TMP}/mds_survey*
19518 }
19519 run_test 225b "Metadata survey sanity with stripe_count = 1"
19520
19521 mcreate_path2fid () {
19522         local mode=$1
19523         local major=$2
19524         local minor=$3
19525         local name=$4
19526         local desc=$5
19527         local path=$DIR/$tdir/$name
19528         local fid
19529         local rc
19530         local fid_path
19531
19532         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19533                 error "cannot create $desc"
19534
19535         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19536         rc=$?
19537         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19538
19539         fid_path=$($LFS fid2path $MOUNT $fid)
19540         rc=$?
19541         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19542
19543         [ "$path" == "$fid_path" ] ||
19544                 error "fid2path returned $fid_path, expected $path"
19545
19546         echo "pass with $path and $fid"
19547 }
19548
19549 test_226a () {
19550         rm -rf $DIR/$tdir
19551         mkdir -p $DIR/$tdir
19552
19553         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19554         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19555         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19556         mcreate_path2fid 0040666 0 0 dir "directory"
19557         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19558         mcreate_path2fid 0100666 0 0 file "regular file"
19559         mcreate_path2fid 0120666 0 0 link "symbolic link"
19560         mcreate_path2fid 0140666 0 0 sock "socket"
19561 }
19562 run_test 226a "call path2fid and fid2path on files of all type"
19563
19564 test_226b () {
19565         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19566
19567         local MDTIDX=1
19568
19569         rm -rf $DIR/$tdir
19570         mkdir -p $DIR/$tdir
19571         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19572                 error "create remote directory failed"
19573         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19574         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19575                                 "character special file (null)"
19576         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19577                                 "character special file (no device)"
19578         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19579         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19580                                 "block special file (loop)"
19581         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19582         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19583         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19584 }
19585 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19586
19587 test_226c () {
19588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19589         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19590                 skip "Need MDS version at least 2.13.55"
19591
19592         local submnt=/mnt/submnt
19593         local srcfile=/etc/passwd
19594         local dstfile=$submnt/passwd
19595         local path
19596         local fid
19597
19598         rm -rf $DIR/$tdir
19599         rm -rf $submnt
19600         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19601                 error "create remote directory failed"
19602         mkdir -p $submnt || error "create $submnt failed"
19603         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19604                 error "mount $submnt failed"
19605         stack_trap "umount $submnt" EXIT
19606
19607         cp $srcfile $dstfile
19608         fid=$($LFS path2fid $dstfile)
19609         path=$($LFS fid2path $submnt "$fid")
19610         [ "$path" = "$dstfile" ] ||
19611                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19612 }
19613 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19614
19615 # LU-1299 Executing or running ldd on a truncated executable does not
19616 # cause an out-of-memory condition.
19617 test_227() {
19618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19619         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19620
19621         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19622         chmod +x $MOUNT/date
19623
19624         $MOUNT/date > /dev/null
19625         ldd $MOUNT/date > /dev/null
19626         rm -f $MOUNT/date
19627 }
19628 run_test 227 "running truncated executable does not cause OOM"
19629
19630 # LU-1512 try to reuse idle OI blocks
19631 test_228a() {
19632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19633         remote_mds_nodsh && skip "remote MDS with nodsh"
19634         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19635
19636         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19637         local myDIR=$DIR/$tdir
19638
19639         mkdir -p $myDIR
19640         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19641         $LCTL set_param fail_loc=0x80001002
19642         createmany -o $myDIR/t- 10000
19643         $LCTL set_param fail_loc=0
19644         # The guard is current the largest FID holder
19645         touch $myDIR/guard
19646         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19647                     tr -d '[')
19648         local IDX=$(($SEQ % 64))
19649
19650         do_facet $SINGLEMDS sync
19651         # Make sure journal flushed.
19652         sleep 6
19653         local blk1=$(do_facet $SINGLEMDS \
19654                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19655                      grep Blockcount | awk '{print $4}')
19656
19657         # Remove old files, some OI blocks will become idle.
19658         unlinkmany $myDIR/t- 10000
19659         # Create new files, idle OI blocks should be reused.
19660         createmany -o $myDIR/t- 2000
19661         do_facet $SINGLEMDS sync
19662         # Make sure journal flushed.
19663         sleep 6
19664         local blk2=$(do_facet $SINGLEMDS \
19665                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19666                      grep Blockcount | awk '{print $4}')
19667
19668         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19669 }
19670 run_test 228a "try to reuse idle OI blocks"
19671
19672 test_228b() {
19673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19674         remote_mds_nodsh && skip "remote MDS with nodsh"
19675         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19676
19677         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19678         local myDIR=$DIR/$tdir
19679
19680         mkdir -p $myDIR
19681         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19682         $LCTL set_param fail_loc=0x80001002
19683         createmany -o $myDIR/t- 10000
19684         $LCTL set_param fail_loc=0
19685         # The guard is current the largest FID holder
19686         touch $myDIR/guard
19687         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19688                     tr -d '[')
19689         local IDX=$(($SEQ % 64))
19690
19691         do_facet $SINGLEMDS sync
19692         # Make sure journal flushed.
19693         sleep 6
19694         local blk1=$(do_facet $SINGLEMDS \
19695                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19696                      grep Blockcount | awk '{print $4}')
19697
19698         # Remove old files, some OI blocks will become idle.
19699         unlinkmany $myDIR/t- 10000
19700
19701         # stop the MDT
19702         stop $SINGLEMDS || error "Fail to stop MDT."
19703         # remount the MDT
19704         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19705                 error "Fail to start MDT."
19706
19707         df $MOUNT || error "Fail to df."
19708         # Create new files, idle OI blocks should be reused.
19709         createmany -o $myDIR/t- 2000
19710         do_facet $SINGLEMDS sync
19711         # Make sure journal flushed.
19712         sleep 6
19713         local blk2=$(do_facet $SINGLEMDS \
19714                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19715                      grep Blockcount | awk '{print $4}')
19716
19717         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19718 }
19719 run_test 228b "idle OI blocks can be reused after MDT restart"
19720
19721 #LU-1881
19722 test_228c() {
19723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19724         remote_mds_nodsh && skip "remote MDS with nodsh"
19725         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19726
19727         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19728         local myDIR=$DIR/$tdir
19729
19730         mkdir -p $myDIR
19731         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19732         $LCTL set_param fail_loc=0x80001002
19733         # 20000 files can guarantee there are index nodes in the OI file
19734         createmany -o $myDIR/t- 20000
19735         $LCTL set_param fail_loc=0
19736         # The guard is current the largest FID holder
19737         touch $myDIR/guard
19738         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19739                     tr -d '[')
19740         local IDX=$(($SEQ % 64))
19741
19742         do_facet $SINGLEMDS sync
19743         # Make sure journal flushed.
19744         sleep 6
19745         local blk1=$(do_facet $SINGLEMDS \
19746                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19747                      grep Blockcount | awk '{print $4}')
19748
19749         # Remove old files, some OI blocks will become idle.
19750         unlinkmany $myDIR/t- 20000
19751         rm -f $myDIR/guard
19752         # The OI file should become empty now
19753
19754         # Create new files, idle OI blocks should be reused.
19755         createmany -o $myDIR/t- 2000
19756         do_facet $SINGLEMDS sync
19757         # Make sure journal flushed.
19758         sleep 6
19759         local blk2=$(do_facet $SINGLEMDS \
19760                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19761                      grep Blockcount | awk '{print $4}')
19762
19763         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19764 }
19765 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19766
19767 test_229() { # LU-2482, LU-3448
19768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19769         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19770         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19771                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19772
19773         rm -f $DIR/$tfile
19774
19775         # Create a file with a released layout and stripe count 2.
19776         $MULTIOP $DIR/$tfile H2c ||
19777                 error "failed to create file with released layout"
19778
19779         $LFS getstripe -v $DIR/$tfile
19780
19781         local pattern=$($LFS getstripe -L $DIR/$tfile)
19782         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19783
19784         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19785                 error "getstripe"
19786         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19787         stat $DIR/$tfile || error "failed to stat released file"
19788
19789         chown $RUNAS_ID $DIR/$tfile ||
19790                 error "chown $RUNAS_ID $DIR/$tfile failed"
19791
19792         chgrp $RUNAS_ID $DIR/$tfile ||
19793                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19794
19795         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19796         rm $DIR/$tfile || error "failed to remove released file"
19797 }
19798 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19799
19800 test_230a() {
19801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19803         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19804                 skip "Need MDS version at least 2.11.52"
19805
19806         local MDTIDX=1
19807
19808         test_mkdir $DIR/$tdir
19809         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19810         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19811         [ $mdt_idx -ne 0 ] &&
19812                 error "create local directory on wrong MDT $mdt_idx"
19813
19814         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19815                         error "create remote directory failed"
19816         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19817         [ $mdt_idx -ne $MDTIDX ] &&
19818                 error "create remote directory on wrong MDT $mdt_idx"
19819
19820         createmany -o $DIR/$tdir/test_230/t- 10 ||
19821                 error "create files on remote directory failed"
19822         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19823         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19824         rm -r $DIR/$tdir || error "unlink remote directory failed"
19825 }
19826 run_test 230a "Create remote directory and files under the remote directory"
19827
19828 test_230b() {
19829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19830         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19831         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19832                 skip "Need MDS version at least 2.11.52"
19833
19834         local MDTIDX=1
19835         local mdt_index
19836         local i
19837         local file
19838         local pid
19839         local stripe_count
19840         local migrate_dir=$DIR/$tdir/migrate_dir
19841         local other_dir=$DIR/$tdir/other_dir
19842
19843         test_mkdir $DIR/$tdir
19844         test_mkdir -i0 -c1 $migrate_dir
19845         test_mkdir -i0 -c1 $other_dir
19846         for ((i=0; i<10; i++)); do
19847                 mkdir -p $migrate_dir/dir_${i}
19848                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19849                         error "create files under remote dir failed $i"
19850         done
19851
19852         cp /etc/passwd $migrate_dir/$tfile
19853         cp /etc/passwd $other_dir/$tfile
19854         chattr +SAD $migrate_dir
19855         chattr +SAD $migrate_dir/$tfile
19856
19857         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19858         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19859         local old_dir_mode=$(stat -c%f $migrate_dir)
19860         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19861
19862         mkdir -p $migrate_dir/dir_default_stripe2
19863         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19864         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19865
19866         mkdir -p $other_dir
19867         ln $migrate_dir/$tfile $other_dir/luna
19868         ln $migrate_dir/$tfile $migrate_dir/sofia
19869         ln $other_dir/$tfile $migrate_dir/david
19870         ln -s $migrate_dir/$tfile $other_dir/zachary
19871         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19872         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19873
19874         local len
19875         local lnktgt
19876
19877         # inline symlink
19878         for len in 58 59 60; do
19879                 lnktgt=$(str_repeat 'l' $len)
19880                 touch $migrate_dir/$lnktgt
19881                 ln -s $lnktgt $migrate_dir/${len}char_ln
19882         done
19883
19884         # PATH_MAX
19885         for len in 4094 4095; do
19886                 lnktgt=$(str_repeat 'l' $len)
19887                 ln -s $lnktgt $migrate_dir/${len}char_ln
19888         done
19889
19890         # NAME_MAX
19891         for len in 254 255; do
19892                 touch $migrate_dir/$(str_repeat 'l' $len)
19893         done
19894
19895         $LFS migrate -m $MDTIDX $migrate_dir ||
19896                 error "fails on migrating remote dir to MDT1"
19897
19898         echo "migratate to MDT1, then checking.."
19899         for ((i = 0; i < 10; i++)); do
19900                 for file in $(find $migrate_dir/dir_${i}); do
19901                         mdt_index=$($LFS getstripe -m $file)
19902                         # broken symlink getstripe will fail
19903                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19904                                 error "$file is not on MDT${MDTIDX}"
19905                 done
19906         done
19907
19908         # the multiple link file should still in MDT0
19909         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19910         [ $mdt_index == 0 ] ||
19911                 error "$file is not on MDT${MDTIDX}"
19912
19913         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19914         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19915                 error " expect $old_dir_flag get $new_dir_flag"
19916
19917         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19918         [ "$old_file_flag" = "$new_file_flag" ] ||
19919                 error " expect $old_file_flag get $new_file_flag"
19920
19921         local new_dir_mode=$(stat -c%f $migrate_dir)
19922         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19923                 error "expect mode $old_dir_mode get $new_dir_mode"
19924
19925         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19926         [ "$old_file_mode" = "$new_file_mode" ] ||
19927                 error "expect mode $old_file_mode get $new_file_mode"
19928
19929         diff /etc/passwd $migrate_dir/$tfile ||
19930                 error "$tfile different after migration"
19931
19932         diff /etc/passwd $other_dir/luna ||
19933                 error "luna different after migration"
19934
19935         diff /etc/passwd $migrate_dir/sofia ||
19936                 error "sofia different after migration"
19937
19938         diff /etc/passwd $migrate_dir/david ||
19939                 error "david different after migration"
19940
19941         diff /etc/passwd $other_dir/zachary ||
19942                 error "zachary different after migration"
19943
19944         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19945                 error "${tfile}_ln different after migration"
19946
19947         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19948                 error "${tfile}_ln_other different after migration"
19949
19950         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19951         [ $stripe_count = 2 ] ||
19952                 error "dir strpe_count $d != 2 after migration."
19953
19954         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19955         [ $stripe_count = 2 ] ||
19956                 error "file strpe_count $d != 2 after migration."
19957
19958         #migrate back to MDT0
19959         MDTIDX=0
19960
19961         $LFS migrate -m $MDTIDX $migrate_dir ||
19962                 error "fails on migrating remote dir to MDT0"
19963
19964         echo "migrate back to MDT0, checking.."
19965         for file in $(find $migrate_dir); do
19966                 mdt_index=$($LFS getstripe -m $file)
19967                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19968                         error "$file is not on MDT${MDTIDX}"
19969         done
19970
19971         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19972         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19973                 error " expect $old_dir_flag get $new_dir_flag"
19974
19975         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19976         [ "$old_file_flag" = "$new_file_flag" ] ||
19977                 error " expect $old_file_flag get $new_file_flag"
19978
19979         local new_dir_mode=$(stat -c%f $migrate_dir)
19980         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19981                 error "expect mode $old_dir_mode get $new_dir_mode"
19982
19983         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19984         [ "$old_file_mode" = "$new_file_mode" ] ||
19985                 error "expect mode $old_file_mode get $new_file_mode"
19986
19987         diff /etc/passwd ${migrate_dir}/$tfile ||
19988                 error "$tfile different after migration"
19989
19990         diff /etc/passwd ${other_dir}/luna ||
19991                 error "luna different after migration"
19992
19993         diff /etc/passwd ${migrate_dir}/sofia ||
19994                 error "sofia different after migration"
19995
19996         diff /etc/passwd ${other_dir}/zachary ||
19997                 error "zachary different after migration"
19998
19999         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20000                 error "${tfile}_ln different after migration"
20001
20002         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20003                 error "${tfile}_ln_other different after migration"
20004
20005         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20006         [ $stripe_count = 2 ] ||
20007                 error "dir strpe_count $d != 2 after migration."
20008
20009         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20010         [ $stripe_count = 2 ] ||
20011                 error "file strpe_count $d != 2 after migration."
20012
20013         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20014 }
20015 run_test 230b "migrate directory"
20016
20017 test_230c() {
20018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20020         remote_mds_nodsh && skip "remote MDS with nodsh"
20021         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20022                 skip "Need MDS version at least 2.11.52"
20023
20024         local MDTIDX=1
20025         local total=3
20026         local mdt_index
20027         local file
20028         local migrate_dir=$DIR/$tdir/migrate_dir
20029
20030         #If migrating directory fails in the middle, all entries of
20031         #the directory is still accessiable.
20032         test_mkdir $DIR/$tdir
20033         test_mkdir -i0 -c1 $migrate_dir
20034         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20035         stat $migrate_dir
20036         createmany -o $migrate_dir/f $total ||
20037                 error "create files under ${migrate_dir} failed"
20038
20039         # fail after migrating top dir, and this will fail only once, so the
20040         # first sub file migration will fail (currently f3), others succeed.
20041         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20042         do_facet mds1 lctl set_param fail_loc=0x1801
20043         local t=$(ls $migrate_dir | wc -l)
20044         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20045                 error "migrate should fail"
20046         local u=$(ls $migrate_dir | wc -l)
20047         [ "$u" == "$t" ] || error "$u != $t during migration"
20048
20049         # add new dir/file should succeed
20050         mkdir $migrate_dir/dir ||
20051                 error "mkdir failed under migrating directory"
20052         touch $migrate_dir/file ||
20053                 error "create file failed under migrating directory"
20054
20055         # add file with existing name should fail
20056         for file in $migrate_dir/f*; do
20057                 stat $file > /dev/null || error "stat $file failed"
20058                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20059                         error "open(O_CREAT|O_EXCL) $file should fail"
20060                 $MULTIOP $file m && error "create $file should fail"
20061                 touch $DIR/$tdir/remote_dir/$tfile ||
20062                         error "touch $tfile failed"
20063                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20064                         error "link $file should fail"
20065                 mdt_index=$($LFS getstripe -m $file)
20066                 if [ $mdt_index == 0 ]; then
20067                         # file failed to migrate is not allowed to rename to
20068                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20069                                 error "rename to $file should fail"
20070                 else
20071                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20072                                 error "rename to $file failed"
20073                 fi
20074                 echo hello >> $file || error "write $file failed"
20075         done
20076
20077         # resume migration with different options should fail
20078         $LFS migrate -m 0 $migrate_dir &&
20079                 error "migrate -m 0 $migrate_dir should fail"
20080
20081         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20082                 error "migrate -c 2 $migrate_dir should fail"
20083
20084         # resume migration should succeed
20085         $LFS migrate -m $MDTIDX $migrate_dir ||
20086                 error "migrate $migrate_dir failed"
20087
20088         echo "Finish migration, then checking.."
20089         for file in $(find $migrate_dir); do
20090                 mdt_index=$($LFS getstripe -m $file)
20091                 [ $mdt_index == $MDTIDX ] ||
20092                         error "$file is not on MDT${MDTIDX}"
20093         done
20094
20095         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20096 }
20097 run_test 230c "check directory accessiblity if migration failed"
20098
20099 test_230d() {
20100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20101         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20102         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20103                 skip "Need MDS version at least 2.11.52"
20104         # LU-11235
20105         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20106
20107         local migrate_dir=$DIR/$tdir/migrate_dir
20108         local old_index
20109         local new_index
20110         local old_count
20111         local new_count
20112         local new_hash
20113         local mdt_index
20114         local i
20115         local j
20116
20117         old_index=$((RANDOM % MDSCOUNT))
20118         old_count=$((MDSCOUNT - old_index))
20119         new_index=$((RANDOM % MDSCOUNT))
20120         new_count=$((MDSCOUNT - new_index))
20121         new_hash=1 # for all_char
20122
20123         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20124         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20125
20126         test_mkdir $DIR/$tdir
20127         test_mkdir -i $old_index -c $old_count $migrate_dir
20128
20129         for ((i=0; i<100; i++)); do
20130                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20131                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20132                         error "create files under remote dir failed $i"
20133         done
20134
20135         echo -n "Migrate from MDT$old_index "
20136         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20137         echo -n "to MDT$new_index"
20138         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20139         echo
20140
20141         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20142         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20143                 error "migrate remote dir error"
20144
20145         echo "Finish migration, then checking.."
20146         for file in $(find $migrate_dir -maxdepth 1); do
20147                 mdt_index=$($LFS getstripe -m $file)
20148                 if [ $mdt_index -lt $new_index ] ||
20149                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20150                         error "$file is on MDT$mdt_index"
20151                 fi
20152         done
20153
20154         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20155 }
20156 run_test 230d "check migrate big directory"
20157
20158 test_230e() {
20159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20160         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20161         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20162                 skip "Need MDS version at least 2.11.52"
20163
20164         local i
20165         local j
20166         local a_fid
20167         local b_fid
20168
20169         mkdir_on_mdt0 $DIR/$tdir
20170         mkdir $DIR/$tdir/migrate_dir
20171         mkdir $DIR/$tdir/other_dir
20172         touch $DIR/$tdir/migrate_dir/a
20173         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20174         ls $DIR/$tdir/other_dir
20175
20176         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20177                 error "migrate dir fails"
20178
20179         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20180         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20181
20182         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20183         [ $mdt_index == 0 ] || error "a is not on MDT0"
20184
20185         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20186                 error "migrate dir fails"
20187
20188         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20189         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20190
20191         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20192         [ $mdt_index == 1 ] || error "a is not on MDT1"
20193
20194         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20195         [ $mdt_index == 1 ] || error "b is not on MDT1"
20196
20197         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20198         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20199
20200         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20201
20202         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20203 }
20204 run_test 230e "migrate mulitple local link files"
20205
20206 test_230f() {
20207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20208         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20209         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20210                 skip "Need MDS version at least 2.11.52"
20211
20212         local a_fid
20213         local ln_fid
20214
20215         mkdir -p $DIR/$tdir
20216         mkdir $DIR/$tdir/migrate_dir
20217         $LFS mkdir -i1 $DIR/$tdir/other_dir
20218         touch $DIR/$tdir/migrate_dir/a
20219         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20220         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20221         ls $DIR/$tdir/other_dir
20222
20223         # a should be migrated to MDT1, since no other links on MDT0
20224         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20225                 error "#1 migrate dir fails"
20226         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20227         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20228         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20229         [ $mdt_index == 1 ] || error "a is not on MDT1"
20230
20231         # a should stay on MDT1, because it is a mulitple link file
20232         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20233                 error "#2 migrate dir fails"
20234         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20235         [ $mdt_index == 1 ] || error "a is not on MDT1"
20236
20237         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20238                 error "#3 migrate dir fails"
20239
20240         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20241         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20242         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20243
20244         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20245         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20246
20247         # a should be migrated to MDT0, since no other links on MDT1
20248         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20249                 error "#4 migrate dir fails"
20250         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20251         [ $mdt_index == 0 ] || error "a is not on MDT0"
20252
20253         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20254 }
20255 run_test 230f "migrate mulitple remote link files"
20256
20257 test_230g() {
20258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20259         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20260         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20261                 skip "Need MDS version at least 2.11.52"
20262
20263         mkdir -p $DIR/$tdir/migrate_dir
20264
20265         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20266                 error "migrating dir to non-exist MDT succeeds"
20267         true
20268 }
20269 run_test 230g "migrate dir to non-exist MDT"
20270
20271 test_230h() {
20272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20273         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20274         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20275                 skip "Need MDS version at least 2.11.52"
20276
20277         local mdt_index
20278
20279         mkdir -p $DIR/$tdir/migrate_dir
20280
20281         $LFS migrate -m1 $DIR &&
20282                 error "migrating mountpoint1 should fail"
20283
20284         $LFS migrate -m1 $DIR/$tdir/.. &&
20285                 error "migrating mountpoint2 should fail"
20286
20287         # same as mv
20288         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20289                 error "migrating $tdir/migrate_dir/.. should fail"
20290
20291         true
20292 }
20293 run_test 230h "migrate .. and root"
20294
20295 test_230i() {
20296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20297         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20298         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20299                 skip "Need MDS version at least 2.11.52"
20300
20301         mkdir -p $DIR/$tdir/migrate_dir
20302
20303         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20304                 error "migration fails with a tailing slash"
20305
20306         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20307                 error "migration fails with two tailing slashes"
20308 }
20309 run_test 230i "lfs migrate -m tolerates trailing slashes"
20310
20311 test_230j() {
20312         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20313         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20314                 skip "Need MDS version at least 2.11.52"
20315
20316         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20317         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20318                 error "create $tfile failed"
20319         cat /etc/passwd > $DIR/$tdir/$tfile
20320
20321         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20322
20323         cmp /etc/passwd $DIR/$tdir/$tfile ||
20324                 error "DoM file mismatch after migration"
20325 }
20326 run_test 230j "DoM file data not changed after dir migration"
20327
20328 test_230k() {
20329         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20330         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20331                 skip "Need MDS version at least 2.11.56"
20332
20333         local total=20
20334         local files_on_starting_mdt=0
20335
20336         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20337         $LFS getdirstripe $DIR/$tdir
20338         for i in $(seq $total); do
20339                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20340                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20341                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20342         done
20343
20344         echo "$files_on_starting_mdt files on MDT0"
20345
20346         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20347         $LFS getdirstripe $DIR/$tdir
20348
20349         files_on_starting_mdt=0
20350         for i in $(seq $total); do
20351                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20352                         error "file $tfile.$i mismatch after migration"
20353                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20354                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20355         done
20356
20357         echo "$files_on_starting_mdt files on MDT1 after migration"
20358         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20359
20360         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20361         $LFS getdirstripe $DIR/$tdir
20362
20363         files_on_starting_mdt=0
20364         for i in $(seq $total); do
20365                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20366                         error "file $tfile.$i mismatch after 2nd migration"
20367                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20368                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20369         done
20370
20371         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20372         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20373
20374         true
20375 }
20376 run_test 230k "file data not changed after dir migration"
20377
20378 test_230l() {
20379         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20380         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20381                 skip "Need MDS version at least 2.11.56"
20382
20383         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20384         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20385                 error "create files under remote dir failed $i"
20386         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20387 }
20388 run_test 230l "readdir between MDTs won't crash"
20389
20390 test_230m() {
20391         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20392         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20393                 skip "Need MDS version at least 2.11.56"
20394
20395         local MDTIDX=1
20396         local mig_dir=$DIR/$tdir/migrate_dir
20397         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20398         local shortstr="b"
20399         local val
20400
20401         echo "Creating files and dirs with xattrs"
20402         test_mkdir $DIR/$tdir
20403         test_mkdir -i0 -c1 $mig_dir
20404         mkdir $mig_dir/dir
20405         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20406                 error "cannot set xattr attr1 on dir"
20407         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20408                 error "cannot set xattr attr2 on dir"
20409         touch $mig_dir/dir/f0
20410         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20411                 error "cannot set xattr attr1 on file"
20412         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20413                 error "cannot set xattr attr2 on file"
20414         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20415         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20416         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20417         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20418         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20419         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20420         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20421         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20422         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20423
20424         echo "Migrating to MDT1"
20425         $LFS migrate -m $MDTIDX $mig_dir ||
20426                 error "fails on migrating dir to MDT1"
20427
20428         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20429         echo "Checking xattrs"
20430         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20431         [ "$val" = $longstr ] ||
20432                 error "expecting xattr1 $longstr on dir, found $val"
20433         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20434         [ "$val" = $shortstr ] ||
20435                 error "expecting xattr2 $shortstr on dir, found $val"
20436         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20437         [ "$val" = $longstr ] ||
20438                 error "expecting xattr1 $longstr on file, found $val"
20439         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20440         [ "$val" = $shortstr ] ||
20441                 error "expecting xattr2 $shortstr on file, found $val"
20442 }
20443 run_test 230m "xattrs not changed after dir migration"
20444
20445 test_230n() {
20446         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20447         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20448                 skip "Need MDS version at least 2.13.53"
20449
20450         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20451         cat /etc/hosts > $DIR/$tdir/$tfile
20452         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20453         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20454
20455         cmp /etc/hosts $DIR/$tdir/$tfile ||
20456                 error "File data mismatch after migration"
20457 }
20458 run_test 230n "Dir migration with mirrored file"
20459
20460 test_230o() {
20461         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20462         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20463                 skip "Need MDS version at least 2.13.52"
20464
20465         local mdts=$(comma_list $(mdts_nodes))
20466         local timeout=100
20467         local restripe_status
20468         local delta
20469         local i
20470
20471         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20472
20473         # in case "crush" hash type is not set
20474         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20475
20476         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20477                            mdt.*MDT0000.enable_dir_restripe)
20478         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20479         stack_trap "do_nodes $mdts $LCTL set_param \
20480                     mdt.*.enable_dir_restripe=$restripe_status"
20481
20482         mkdir $DIR/$tdir
20483         createmany -m $DIR/$tdir/f 100 ||
20484                 error "create files under remote dir failed $i"
20485         createmany -d $DIR/$tdir/d 100 ||
20486                 error "create dirs under remote dir failed $i"
20487
20488         for i in $(seq 2 $MDSCOUNT); do
20489                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20490                 $LFS setdirstripe -c $i $DIR/$tdir ||
20491                         error "split -c $i $tdir failed"
20492                 wait_update $HOSTNAME \
20493                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20494                         error "dir split not finished"
20495                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20496                         awk '/migrate/ {sum += $2} END { print sum }')
20497                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20498                 # delta is around total_files/stripe_count
20499                 (( $delta < 200 / (i - 1) + 4 )) ||
20500                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20501         done
20502 }
20503 run_test 230o "dir split"
20504
20505 test_230p() {
20506         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20507         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20508                 skip "Need MDS version at least 2.13.52"
20509
20510         local mdts=$(comma_list $(mdts_nodes))
20511         local timeout=100
20512         local restripe_status
20513         local delta
20514         local c
20515
20516         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20517
20518         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20519
20520         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20521                            mdt.*MDT0000.enable_dir_restripe)
20522         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20523         stack_trap "do_nodes $mdts $LCTL set_param \
20524                     mdt.*.enable_dir_restripe=$restripe_status"
20525
20526         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20527         createmany -m $DIR/$tdir/f 100 ||
20528                 error "create files under remote dir failed"
20529         createmany -d $DIR/$tdir/d 100 ||
20530                 error "create dirs under remote dir failed"
20531
20532         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20533                 local mdt_hash="crush"
20534
20535                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20536                 $LFS setdirstripe -c $c $DIR/$tdir ||
20537                         error "split -c $c $tdir failed"
20538                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20539                         mdt_hash="$mdt_hash,fixed"
20540                 elif [ $c -eq 1 ]; then
20541                         mdt_hash="none"
20542                 fi
20543                 wait_update $HOSTNAME \
20544                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20545                         error "dir merge not finished"
20546                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20547                         awk '/migrate/ {sum += $2} END { print sum }')
20548                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20549                 # delta is around total_files/stripe_count
20550                 (( delta < 200 / c + 4 )) ||
20551                         error "$delta files migrated >= $((200 / c + 4))"
20552         done
20553 }
20554 run_test 230p "dir merge"
20555
20556 test_230q() {
20557         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20558         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20559                 skip "Need MDS version at least 2.13.52"
20560
20561         local mdts=$(comma_list $(mdts_nodes))
20562         local saved_threshold=$(do_facet mds1 \
20563                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20564         local saved_delta=$(do_facet mds1 \
20565                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20566         local threshold=100
20567         local delta=2
20568         local total=0
20569         local stripe_count=0
20570         local stripe_index
20571         local nr_files
20572         local create
20573
20574         # test with fewer files on ZFS
20575         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20576
20577         stack_trap "do_nodes $mdts $LCTL set_param \
20578                     mdt.*.dir_split_count=$saved_threshold"
20579         stack_trap "do_nodes $mdts $LCTL set_param \
20580                     mdt.*.dir_split_delta=$saved_delta"
20581         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20582         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20583         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20584         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20585         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20586         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20587
20588         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20589         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20590
20591         create=$((threshold * 3 / 2))
20592         while [ $stripe_count -lt $MDSCOUNT ]; do
20593                 createmany -m $DIR/$tdir/f $total $create ||
20594                         error "create sub files failed"
20595                 stat $DIR/$tdir > /dev/null
20596                 total=$((total + create))
20597                 stripe_count=$((stripe_count + delta))
20598                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20599
20600                 wait_update $HOSTNAME \
20601                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20602                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20603
20604                 wait_update $HOSTNAME \
20605                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20606                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20607
20608                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20609                 echo "$nr_files/$total files on MDT$stripe_index after split"
20610                 # allow 10% margin of imbalance with crush hash
20611                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20612                         error "$nr_files files on MDT$stripe_index after split"
20613
20614                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20615                 [ $nr_files -eq $total ] ||
20616                         error "total sub files $nr_files != $total"
20617         done
20618
20619         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20620
20621         echo "fixed layout directory won't auto split"
20622         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20623         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20624                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20625         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20626                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20627 }
20628 run_test 230q "dir auto split"
20629
20630 test_230r() {
20631         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20632         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20633         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20634                 skip "Need MDS version at least 2.13.54"
20635
20636         # maximum amount of local locks:
20637         # parent striped dir - 2 locks
20638         # new stripe in parent to migrate to - 1 lock
20639         # source and target - 2 locks
20640         # Total 5 locks for regular file
20641         mkdir -p $DIR/$tdir
20642         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20643         touch $DIR/$tdir/dir1/eee
20644
20645         # create 4 hardlink for 4 more locks
20646         # Total: 9 locks > RS_MAX_LOCKS (8)
20647         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20648         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20649         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20650         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20651         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20652         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20653         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20654         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20655
20656         cancel_lru_locks mdc
20657
20658         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20659                 error "migrate dir fails"
20660
20661         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20662 }
20663 run_test 230r "migrate with too many local locks"
20664
20665 test_230s() {
20666         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20667                 skip "Need MDS version at least 2.14.52"
20668
20669         local mdts=$(comma_list $(mdts_nodes))
20670         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20671                                 mdt.*MDT0000.enable_dir_restripe)
20672
20673         stack_trap "do_nodes $mdts $LCTL set_param \
20674                     mdt.*.enable_dir_restripe=$restripe_status"
20675
20676         local st
20677         for st in 0 1; do
20678                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20679                 test_mkdir $DIR/$tdir
20680                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20681                         error "$LFS mkdir should return EEXIST if target exists"
20682                 rmdir $DIR/$tdir
20683         done
20684 }
20685 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20686
20687 test_230t()
20688 {
20689         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20690         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20691                 skip "Need MDS version at least 2.14.50"
20692
20693         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20694         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20695         $LFS project -p 1 -s $DIR/$tdir ||
20696                 error "set $tdir project id failed"
20697         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20698                 error "set subdir project id failed"
20699         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20700 }
20701 run_test 230t "migrate directory with project ID set"
20702
20703 test_230u()
20704 {
20705         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20706         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20707                 skip "Need MDS version at least 2.14.53"
20708
20709         local count
20710
20711         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20712         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20713         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20714         for i in $(seq 0 $((MDSCOUNT - 1))); do
20715                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20716                 echo "$count dirs migrated to MDT$i"
20717         done
20718         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20719         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20720 }
20721 run_test 230u "migrate directory by QOS"
20722
20723 test_230v()
20724 {
20725         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20726         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20727                 skip "Need MDS version at least 2.14.53"
20728
20729         local count
20730
20731         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20732         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20733         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20734         for i in $(seq 0 $((MDSCOUNT - 1))); do
20735                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20736                 echo "$count subdirs migrated to MDT$i"
20737                 (( i == 3 )) && (( count > 0 )) &&
20738                         error "subdir shouldn't be migrated to MDT3"
20739         done
20740         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20741         (( count == 3 )) || error "dirs migrated to $count MDTs"
20742 }
20743 run_test 230v "subdir migrated to the MDT where its parent is located"
20744
20745 test_230w() {
20746         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20747         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20748                 skip "Need MDS version at least 2.14.53"
20749
20750         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20751
20752         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20753                 error "migrate failed"
20754
20755         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20756                 error "$tdir stripe count mismatch"
20757
20758         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20759                 error "$tdir/sub is striped"
20760 }
20761 run_test 230w "non-recursive mode dir migration"
20762
20763 test_231a()
20764 {
20765         # For simplicity this test assumes that max_pages_per_rpc
20766         # is the same across all OSCs
20767         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20768         local bulk_size=$((max_pages * PAGE_SIZE))
20769         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20770                                        head -n 1)
20771
20772         mkdir -p $DIR/$tdir
20773         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20774                 error "failed to set stripe with -S ${brw_size}M option"
20775
20776         # clear the OSC stats
20777         $LCTL set_param osc.*.stats=0 &>/dev/null
20778         stop_writeback
20779
20780         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20781         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20782                 oflag=direct &>/dev/null || error "dd failed"
20783
20784         sync; sleep 1; sync # just to be safe
20785         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20786         if [ x$nrpcs != "x1" ]; then
20787                 $LCTL get_param osc.*.stats
20788                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20789         fi
20790
20791         start_writeback
20792         # Drop the OSC cache, otherwise we will read from it
20793         cancel_lru_locks osc
20794
20795         # clear the OSC stats
20796         $LCTL set_param osc.*.stats=0 &>/dev/null
20797
20798         # Client reads $bulk_size.
20799         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20800                 iflag=direct &>/dev/null || error "dd failed"
20801
20802         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20803         if [ x$nrpcs != "x1" ]; then
20804                 $LCTL get_param osc.*.stats
20805                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20806         fi
20807 }
20808 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20809
20810 test_231b() {
20811         mkdir -p $DIR/$tdir
20812         local i
20813         for i in {0..1023}; do
20814                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20815                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20816                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20817         done
20818         sync
20819 }
20820 run_test 231b "must not assert on fully utilized OST request buffer"
20821
20822 test_232a() {
20823         mkdir -p $DIR/$tdir
20824         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20825
20826         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20827         do_facet ost1 $LCTL set_param fail_loc=0x31c
20828
20829         # ignore dd failure
20830         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20831
20832         do_facet ost1 $LCTL set_param fail_loc=0
20833         umount_client $MOUNT || error "umount failed"
20834         mount_client $MOUNT || error "mount failed"
20835         stop ost1 || error "cannot stop ost1"
20836         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20837 }
20838 run_test 232a "failed lock should not block umount"
20839
20840 test_232b() {
20841         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20842                 skip "Need MDS version at least 2.10.58"
20843
20844         mkdir -p $DIR/$tdir
20845         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20846         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20847         sync
20848         cancel_lru_locks osc
20849
20850         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20851         do_facet ost1 $LCTL set_param fail_loc=0x31c
20852
20853         # ignore failure
20854         $LFS data_version $DIR/$tdir/$tfile || true
20855
20856         do_facet ost1 $LCTL set_param fail_loc=0
20857         umount_client $MOUNT || error "umount failed"
20858         mount_client $MOUNT || error "mount failed"
20859         stop ost1 || error "cannot stop ost1"
20860         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20861 }
20862 run_test 232b "failed data version lock should not block umount"
20863
20864 test_233a() {
20865         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20866                 skip "Need MDS version at least 2.3.64"
20867         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20868
20869         local fid=$($LFS path2fid $MOUNT)
20870
20871         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20872                 error "cannot access $MOUNT using its FID '$fid'"
20873 }
20874 run_test 233a "checking that OBF of the FS root succeeds"
20875
20876 test_233b() {
20877         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20878                 skip "Need MDS version at least 2.5.90"
20879         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20880
20881         local fid=$($LFS path2fid $MOUNT/.lustre)
20882
20883         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20884                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20885
20886         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20887         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20888                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20889 }
20890 run_test 233b "checking that OBF of the FS .lustre succeeds"
20891
20892 test_234() {
20893         local p="$TMP/sanityN-$TESTNAME.parameters"
20894         save_lustre_params client "llite.*.xattr_cache" > $p
20895         lctl set_param llite.*.xattr_cache 1 ||
20896                 skip_env "xattr cache is not supported"
20897
20898         mkdir -p $DIR/$tdir || error "mkdir failed"
20899         touch $DIR/$tdir/$tfile || error "touch failed"
20900         # OBD_FAIL_LLITE_XATTR_ENOMEM
20901         $LCTL set_param fail_loc=0x1405
20902         getfattr -n user.attr $DIR/$tdir/$tfile &&
20903                 error "getfattr should have failed with ENOMEM"
20904         $LCTL set_param fail_loc=0x0
20905         rm -rf $DIR/$tdir
20906
20907         restore_lustre_params < $p
20908         rm -f $p
20909 }
20910 run_test 234 "xattr cache should not crash on ENOMEM"
20911
20912 test_235() {
20913         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20914                 skip "Need MDS version at least 2.4.52"
20915
20916         flock_deadlock $DIR/$tfile
20917         local RC=$?
20918         case $RC in
20919                 0)
20920                 ;;
20921                 124) error "process hangs on a deadlock"
20922                 ;;
20923                 *) error "error executing flock_deadlock $DIR/$tfile"
20924                 ;;
20925         esac
20926 }
20927 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20928
20929 #LU-2935
20930 test_236() {
20931         check_swap_layouts_support
20932
20933         local ref1=/etc/passwd
20934         local ref2=/etc/group
20935         local file1=$DIR/$tdir/f1
20936         local file2=$DIR/$tdir/f2
20937
20938         test_mkdir -c1 $DIR/$tdir
20939         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20940         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20941         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20942         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20943         local fd=$(free_fd)
20944         local cmd="exec $fd<>$file2"
20945         eval $cmd
20946         rm $file2
20947         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20948                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20949         cmd="exec $fd>&-"
20950         eval $cmd
20951         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20952
20953         #cleanup
20954         rm -rf $DIR/$tdir
20955 }
20956 run_test 236 "Layout swap on open unlinked file"
20957
20958 # LU-4659 linkea consistency
20959 test_238() {
20960         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20961                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20962                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20963                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20964
20965         touch $DIR/$tfile
20966         ln $DIR/$tfile $DIR/$tfile.lnk
20967         touch $DIR/$tfile.new
20968         mv $DIR/$tfile.new $DIR/$tfile
20969         local fid1=$($LFS path2fid $DIR/$tfile)
20970         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20971         local path1=$($LFS fid2path $FSNAME "$fid1")
20972         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20973         local path2=$($LFS fid2path $FSNAME "$fid2")
20974         [ $tfile.lnk == $path2 ] ||
20975                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20976         rm -f $DIR/$tfile*
20977 }
20978 run_test 238 "Verify linkea consistency"
20979
20980 test_239A() { # was test_239
20981         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20982                 skip "Need MDS version at least 2.5.60"
20983
20984         local list=$(comma_list $(mdts_nodes))
20985
20986         mkdir -p $DIR/$tdir
20987         createmany -o $DIR/$tdir/f- 5000
20988         unlinkmany $DIR/$tdir/f- 5000
20989         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20990                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20991         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20992                         osp.*MDT*.sync_in_flight" | calc_sum)
20993         [ "$changes" -eq 0 ] || error "$changes not synced"
20994 }
20995 run_test 239A "osp_sync test"
20996
20997 test_239a() { #LU-5297
20998         remote_mds_nodsh && skip "remote MDS with nodsh"
20999
21000         touch $DIR/$tfile
21001         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21002         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21003         chgrp $RUNAS_GID $DIR/$tfile
21004         wait_delete_completed
21005 }
21006 run_test 239a "process invalid osp sync record correctly"
21007
21008 test_239b() { #LU-5297
21009         remote_mds_nodsh && skip "remote MDS with nodsh"
21010
21011         touch $DIR/$tfile1
21012         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21013         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21014         chgrp $RUNAS_GID $DIR/$tfile1
21015         wait_delete_completed
21016         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21017         touch $DIR/$tfile2
21018         chgrp $RUNAS_GID $DIR/$tfile2
21019         wait_delete_completed
21020 }
21021 run_test 239b "process osp sync record with ENOMEM error correctly"
21022
21023 test_240() {
21024         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21025         remote_mds_nodsh && skip "remote MDS with nodsh"
21026
21027         mkdir -p $DIR/$tdir
21028
21029         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21030                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21031         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21032                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21033
21034         umount_client $MOUNT || error "umount failed"
21035         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21036         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21037         mount_client $MOUNT || error "failed to mount client"
21038
21039         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21040         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21041 }
21042 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21043
21044 test_241_bio() {
21045         local count=$1
21046         local bsize=$2
21047
21048         for LOOP in $(seq $count); do
21049                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21050                 cancel_lru_locks $OSC || true
21051         done
21052 }
21053
21054 test_241_dio() {
21055         local count=$1
21056         local bsize=$2
21057
21058         for LOOP in $(seq $1); do
21059                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21060                         2>/dev/null
21061         done
21062 }
21063
21064 test_241a() { # was test_241
21065         local bsize=$PAGE_SIZE
21066
21067         (( bsize < 40960 )) && bsize=40960
21068         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21069         ls -la $DIR/$tfile
21070         cancel_lru_locks $OSC
21071         test_241_bio 1000 $bsize &
21072         PID=$!
21073         test_241_dio 1000 $bsize
21074         wait $PID
21075 }
21076 run_test 241a "bio vs dio"
21077
21078 test_241b() {
21079         local bsize=$PAGE_SIZE
21080
21081         (( bsize < 40960 )) && bsize=40960
21082         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21083         ls -la $DIR/$tfile
21084         test_241_dio 1000 $bsize &
21085         PID=$!
21086         test_241_dio 1000 $bsize
21087         wait $PID
21088 }
21089 run_test 241b "dio vs dio"
21090
21091 test_242() {
21092         remote_mds_nodsh && skip "remote MDS with nodsh"
21093
21094         mkdir_on_mdt0 $DIR/$tdir
21095         touch $DIR/$tdir/$tfile
21096
21097         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21098         do_facet mds1 lctl set_param fail_loc=0x105
21099         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21100
21101         do_facet mds1 lctl set_param fail_loc=0
21102         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21103 }
21104 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21105
21106 test_243()
21107 {
21108         test_mkdir $DIR/$tdir
21109         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21110 }
21111 run_test 243 "various group lock tests"
21112
21113 test_244a()
21114 {
21115         test_mkdir $DIR/$tdir
21116         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21117         sendfile_grouplock $DIR/$tdir/$tfile || \
21118                 error "sendfile+grouplock failed"
21119         rm -rf $DIR/$tdir
21120 }
21121 run_test 244a "sendfile with group lock tests"
21122
21123 test_244b()
21124 {
21125         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21126
21127         local threads=50
21128         local size=$((1024*1024))
21129
21130         test_mkdir $DIR/$tdir
21131         for i in $(seq 1 $threads); do
21132                 local file=$DIR/$tdir/file_$((i / 10))
21133                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21134                 local pids[$i]=$!
21135         done
21136         for i in $(seq 1 $threads); do
21137                 wait ${pids[$i]}
21138         done
21139 }
21140 run_test 244b "multi-threaded write with group lock"
21141
21142 test_245a() {
21143         local flagname="multi_mod_rpcs"
21144         local connect_data_name="max_mod_rpcs"
21145         local out
21146
21147         # check if multiple modify RPCs flag is set
21148         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21149                 grep "connect_flags:")
21150         echo "$out"
21151
21152         echo "$out" | grep -qw $flagname
21153         if [ $? -ne 0 ]; then
21154                 echo "connect flag $flagname is not set"
21155                 return
21156         fi
21157
21158         # check if multiple modify RPCs data is set
21159         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21160         echo "$out"
21161
21162         echo "$out" | grep -qw $connect_data_name ||
21163                 error "import should have connect data $connect_data_name"
21164 }
21165 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21166
21167 test_245b() {
21168         local flagname="multi_mod_rpcs"
21169         local connect_data_name="max_mod_rpcs"
21170         local out
21171
21172         remote_mds_nodsh && skip "remote MDS with nodsh"
21173         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21174
21175         # check if multiple modify RPCs flag is set
21176         out=$(do_facet mds1 \
21177               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21178               grep "connect_flags:")
21179         echo "$out"
21180
21181         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21182
21183         # check if multiple modify RPCs data is set
21184         out=$(do_facet mds1 \
21185               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21186
21187         [[ "$out" =~ $connect_data_name ]] ||
21188                 {
21189                         echo "$out"
21190                         error "missing connect data $connect_data_name"
21191                 }
21192 }
21193 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21194
21195 cleanup_247() {
21196         local submount=$1
21197
21198         trap 0
21199         umount_client $submount
21200         rmdir $submount
21201 }
21202
21203 test_247a() {
21204         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21205                 grep -q subtree ||
21206                 skip_env "Fileset feature is not supported"
21207
21208         local submount=${MOUNT}_$tdir
21209
21210         mkdir $MOUNT/$tdir
21211         mkdir -p $submount || error "mkdir $submount failed"
21212         FILESET="$FILESET/$tdir" mount_client $submount ||
21213                 error "mount $submount failed"
21214         trap "cleanup_247 $submount" EXIT
21215         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21216         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21217                 error "read $MOUNT/$tdir/$tfile failed"
21218         cleanup_247 $submount
21219 }
21220 run_test 247a "mount subdir as fileset"
21221
21222 test_247b() {
21223         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21224                 skip_env "Fileset feature is not supported"
21225
21226         local submount=${MOUNT}_$tdir
21227
21228         rm -rf $MOUNT/$tdir
21229         mkdir -p $submount || error "mkdir $submount failed"
21230         SKIP_FILESET=1
21231         FILESET="$FILESET/$tdir" mount_client $submount &&
21232                 error "mount $submount should fail"
21233         rmdir $submount
21234 }
21235 run_test 247b "mount subdir that dose not exist"
21236
21237 test_247c() {
21238         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21239                 skip_env "Fileset feature is not supported"
21240
21241         local submount=${MOUNT}_$tdir
21242
21243         mkdir -p $MOUNT/$tdir/dir1
21244         mkdir -p $submount || error "mkdir $submount failed"
21245         trap "cleanup_247 $submount" EXIT
21246         FILESET="$FILESET/$tdir" mount_client $submount ||
21247                 error "mount $submount failed"
21248         local fid=$($LFS path2fid $MOUNT/)
21249         $LFS fid2path $submount $fid && error "fid2path should fail"
21250         cleanup_247 $submount
21251 }
21252 run_test 247c "running fid2path outside subdirectory root"
21253
21254 test_247d() {
21255         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21256                 skip "Fileset feature is not supported"
21257
21258         local submount=${MOUNT}_$tdir
21259
21260         mkdir -p $MOUNT/$tdir/dir1
21261         mkdir -p $submount || error "mkdir $submount failed"
21262         FILESET="$FILESET/$tdir" mount_client $submount ||
21263                 error "mount $submount failed"
21264         trap "cleanup_247 $submount" EXIT
21265
21266         local td=$submount/dir1
21267         local fid=$($LFS path2fid $td)
21268         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21269
21270         # check that we get the same pathname back
21271         local rootpath
21272         local found
21273         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21274                 echo "$rootpath $fid"
21275                 found=$($LFS fid2path $rootpath "$fid")
21276                 [ -n "$found" ] || error "fid2path should succeed"
21277                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21278         done
21279         # check wrong root path format
21280         rootpath=$submount"_wrong"
21281         found=$($LFS fid2path $rootpath "$fid")
21282         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21283
21284         cleanup_247 $submount
21285 }
21286 run_test 247d "running fid2path inside subdirectory root"
21287
21288 # LU-8037
21289 test_247e() {
21290         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21291                 grep -q subtree ||
21292                 skip "Fileset feature is not supported"
21293
21294         local submount=${MOUNT}_$tdir
21295
21296         mkdir $MOUNT/$tdir
21297         mkdir -p $submount || error "mkdir $submount failed"
21298         FILESET="$FILESET/.." mount_client $submount &&
21299                 error "mount $submount should fail"
21300         rmdir $submount
21301 }
21302 run_test 247e "mount .. as fileset"
21303
21304 test_247f() {
21305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21306         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21307                 skip "Need at least version 2.13.52"
21308         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21309                 skip "Need at least version 2.14.50"
21310         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21311                 grep -q subtree ||
21312                 skip "Fileset feature is not supported"
21313
21314         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21315         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21316                 error "mkdir remote failed"
21317         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21318                 error "mkdir remote/subdir failed"
21319         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21320                 error "mkdir striped failed"
21321         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21322
21323         local submount=${MOUNT}_$tdir
21324
21325         mkdir -p $submount || error "mkdir $submount failed"
21326         stack_trap "rmdir $submount"
21327
21328         local dir
21329         local stat
21330         local fileset=$FILESET
21331         local mdts=$(comma_list $(mdts_nodes))
21332
21333         stat=$(do_facet mds1 $LCTL get_param -n \
21334                 mdt.*MDT0000.enable_remote_subdir_mount)
21335         stack_trap "do_nodes $mdts $LCTL set_param \
21336                 mdt.*.enable_remote_subdir_mount=$stat"
21337
21338         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21339         stack_trap "umount_client $submount"
21340         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21341                 error "mount remote dir $dir should fail"
21342
21343         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21344                 $tdir/striped/. ; do
21345                 FILESET="$fileset/$dir" mount_client $submount ||
21346                         error "mount $dir failed"
21347                 umount_client $submount
21348         done
21349
21350         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21351         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21352                 error "mount $tdir/remote failed"
21353 }
21354 run_test 247f "mount striped or remote directory as fileset"
21355
21356 test_247g() {
21357         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21358         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21359                 skip "Need at least version 2.14.50"
21360
21361         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21362                 error "mkdir $tdir failed"
21363         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21364
21365         local submount=${MOUNT}_$tdir
21366
21367         mkdir -p $submount || error "mkdir $submount failed"
21368         stack_trap "rmdir $submount"
21369
21370         FILESET="$fileset/$tdir" mount_client $submount ||
21371                 error "mount $dir failed"
21372         stack_trap "umount $submount"
21373
21374         local mdts=$(comma_list $(mdts_nodes))
21375
21376         local nrpcs
21377
21378         stat $submount > /dev/null
21379         cancel_lru_locks $MDC
21380         stat $submount > /dev/null
21381         stat $submount/$tfile > /dev/null
21382         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21383         stat $submount/$tfile > /dev/null
21384         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21385                 awk '/getattr/ {sum += $2} END {print sum}')
21386
21387         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21388 }
21389 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21390
21391 test_248a() {
21392         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21393         [ -z "$fast_read_sav" ] && skip "no fast read support"
21394
21395         # create a large file for fast read verification
21396         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21397
21398         # make sure the file is created correctly
21399         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21400                 { rm -f $DIR/$tfile; skip "file creation error"; }
21401
21402         echo "Test 1: verify that fast read is 4 times faster on cache read"
21403
21404         # small read with fast read enabled
21405         $LCTL set_param -n llite.*.fast_read=1
21406         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21407                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21408                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21409         # small read with fast read disabled
21410         $LCTL set_param -n llite.*.fast_read=0
21411         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21412                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21413                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21414
21415         # verify that fast read is 4 times faster for cache read
21416         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21417                 error_not_in_vm "fast read was not 4 times faster: " \
21418                            "$t_fast vs $t_slow"
21419
21420         echo "Test 2: verify the performance between big and small read"
21421         $LCTL set_param -n llite.*.fast_read=1
21422
21423         # 1k non-cache read
21424         cancel_lru_locks osc
21425         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21426                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21427                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21428
21429         # 1M non-cache read
21430         cancel_lru_locks osc
21431         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21432                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21433                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21434
21435         # verify that big IO is not 4 times faster than small IO
21436         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21437                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21438
21439         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21440         rm -f $DIR/$tfile
21441 }
21442 run_test 248a "fast read verification"
21443
21444 test_248b() {
21445         # Default short_io_bytes=16384, try both smaller and larger sizes.
21446         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21447         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21448         echo "bs=53248 count=113 normal buffered write"
21449         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21450                 error "dd of initial data file failed"
21451         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21452
21453         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21454         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21455                 error "dd with sync normal writes failed"
21456         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21457
21458         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21459         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21460                 error "dd with sync small writes failed"
21461         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21462
21463         cancel_lru_locks osc
21464
21465         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21466         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21467         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21468         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21469                 iflag=direct || error "dd with O_DIRECT small read failed"
21470         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21471         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21472                 error "compare $TMP/$tfile.1 failed"
21473
21474         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21475         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21476
21477         # just to see what the maximum tunable value is, and test parsing
21478         echo "test invalid parameter 2MB"
21479         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21480                 error "too-large short_io_bytes allowed"
21481         echo "test maximum parameter 512KB"
21482         # if we can set a larger short_io_bytes, run test regardless of version
21483         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21484                 # older clients may not allow setting it this large, that's OK
21485                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21486                         skip "Need at least client version 2.13.50"
21487                 error "medium short_io_bytes failed"
21488         fi
21489         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21490         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21491
21492         echo "test large parameter 64KB"
21493         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21494         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21495
21496         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21497         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21498                 error "dd with sync large writes failed"
21499         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21500
21501         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21502         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21503         num=$((113 * 4096 / PAGE_SIZE))
21504         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21505         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21506                 error "dd with O_DIRECT large writes failed"
21507         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21508                 error "compare $DIR/$tfile.3 failed"
21509
21510         cancel_lru_locks osc
21511
21512         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21513         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21514                 error "dd with O_DIRECT large read failed"
21515         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21516                 error "compare $TMP/$tfile.2 failed"
21517
21518         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21519         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21520                 error "dd with O_DIRECT large read failed"
21521         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21522                 error "compare $TMP/$tfile.3 failed"
21523 }
21524 run_test 248b "test short_io read and write for both small and large sizes"
21525
21526 test_249() { # LU-7890
21527         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21528                 skip "Need at least version 2.8.54"
21529
21530         rm -f $DIR/$tfile
21531         $LFS setstripe -c 1 $DIR/$tfile
21532         # Offset 2T == 4k * 512M
21533         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21534                 error "dd to 2T offset failed"
21535 }
21536 run_test 249 "Write above 2T file size"
21537
21538 test_250() {
21539         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21540          && skip "no 16TB file size limit on ZFS"
21541
21542         $LFS setstripe -c 1 $DIR/$tfile
21543         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21544         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21545         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21546         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21547                 conv=notrunc,fsync && error "append succeeded"
21548         return 0
21549 }
21550 run_test 250 "Write above 16T limit"
21551
21552 test_251() {
21553         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21554
21555         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21556         #Skip once - writing the first stripe will succeed
21557         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21558         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21559                 error "short write happened"
21560
21561         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21562         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21563                 error "short read happened"
21564
21565         rm -f $DIR/$tfile
21566 }
21567 run_test 251 "Handling short read and write correctly"
21568
21569 test_252() {
21570         remote_mds_nodsh && skip "remote MDS with nodsh"
21571         remote_ost_nodsh && skip "remote OST with nodsh"
21572         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21573                 skip_env "ldiskfs only test"
21574         fi
21575
21576         local tgt
21577         local dev
21578         local out
21579         local uuid
21580         local num
21581         local gen
21582
21583         # check lr_reader on OST0000
21584         tgt=ost1
21585         dev=$(facet_device $tgt)
21586         out=$(do_facet $tgt $LR_READER $dev)
21587         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21588         echo "$out"
21589         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21590         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21591                 error "Invalid uuid returned by $LR_READER on target $tgt"
21592         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21593
21594         # check lr_reader -c on MDT0000
21595         tgt=mds1
21596         dev=$(facet_device $tgt)
21597         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21598                 skip "$LR_READER does not support additional options"
21599         fi
21600         out=$(do_facet $tgt $LR_READER -c $dev)
21601         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21602         echo "$out"
21603         num=$(echo "$out" | grep -c "mdtlov")
21604         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21605                 error "Invalid number of mdtlov clients returned by $LR_READER"
21606         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21607
21608         # check lr_reader -cr on MDT0000
21609         out=$(do_facet $tgt $LR_READER -cr $dev)
21610         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21611         echo "$out"
21612         echo "$out" | grep -q "^reply_data:$" ||
21613                 error "$LR_READER should have returned 'reply_data' section"
21614         num=$(echo "$out" | grep -c "client_generation")
21615         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21616 }
21617 run_test 252 "check lr_reader tool"
21618
21619 test_253() {
21620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21621         remote_mds_nodsh && skip "remote MDS with nodsh"
21622         remote_mgs_nodsh && skip "remote MGS with nodsh"
21623
21624         local ostidx=0
21625         local rc=0
21626         local ost_name=$(ostname_from_index $ostidx)
21627
21628         # on the mdt's osc
21629         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21630         do_facet $SINGLEMDS $LCTL get_param -n \
21631                 osp.$mdtosc_proc1.reserved_mb_high ||
21632                 skip  "remote MDS does not support reserved_mb_high"
21633
21634         rm -rf $DIR/$tdir
21635         wait_mds_ost_sync
21636         wait_delete_completed
21637         mkdir $DIR/$tdir
21638
21639         pool_add $TESTNAME || error "Pool creation failed"
21640         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21641
21642         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21643                 error "Setstripe failed"
21644
21645         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21646
21647         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21648                     grep "watermarks")
21649         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21650
21651         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21652                         osp.$mdtosc_proc1.prealloc_status)
21653         echo "prealloc_status $oa_status"
21654
21655         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21656                 error "File creation should fail"
21657
21658         #object allocation was stopped, but we still able to append files
21659         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21660                 oflag=append || error "Append failed"
21661
21662         rm -f $DIR/$tdir/$tfile.0
21663
21664         # For this test, we want to delete the files we created to go out of
21665         # space but leave the watermark, so we remain nearly out of space
21666         ost_watermarks_enospc_delete_files $tfile $ostidx
21667
21668         wait_delete_completed
21669
21670         sleep_maxage
21671
21672         for i in $(seq 10 12); do
21673                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21674                         2>/dev/null || error "File creation failed after rm"
21675         done
21676
21677         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21678                         osp.$mdtosc_proc1.prealloc_status)
21679         echo "prealloc_status $oa_status"
21680
21681         if (( oa_status != 0 )); then
21682                 error "Object allocation still disable after rm"
21683         fi
21684 }
21685 run_test 253 "Check object allocation limit"
21686
21687 test_254() {
21688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21689         remote_mds_nodsh && skip "remote MDS with nodsh"
21690
21691         local mdt=$(facet_svc $SINGLEMDS)
21692
21693         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21694                 skip "MDS does not support changelog_size"
21695
21696         local cl_user
21697
21698         changelog_register || error "changelog_register failed"
21699
21700         changelog_clear 0 || error "changelog_clear failed"
21701
21702         local size1=$(do_facet $SINGLEMDS \
21703                       $LCTL get_param -n mdd.$mdt.changelog_size)
21704         echo "Changelog size $size1"
21705
21706         rm -rf $DIR/$tdir
21707         $LFS mkdir -i 0 $DIR/$tdir
21708         # change something
21709         mkdir -p $DIR/$tdir/pics/2008/zachy
21710         touch $DIR/$tdir/pics/2008/zachy/timestamp
21711         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21712         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21713         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21714         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21715         rm $DIR/$tdir/pics/desktop.jpg
21716
21717         local size2=$(do_facet $SINGLEMDS \
21718                       $LCTL get_param -n mdd.$mdt.changelog_size)
21719         echo "Changelog size after work $size2"
21720
21721         (( $size2 > $size1 )) ||
21722                 error "new Changelog size=$size2 less than old size=$size1"
21723 }
21724 run_test 254 "Check changelog size"
21725
21726 ladvise_no_type()
21727 {
21728         local type=$1
21729         local file=$2
21730
21731         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21732                 awk -F: '{print $2}' | grep $type > /dev/null
21733         if [ $? -ne 0 ]; then
21734                 return 0
21735         fi
21736         return 1
21737 }
21738
21739 ladvise_no_ioctl()
21740 {
21741         local file=$1
21742
21743         lfs ladvise -a willread $file > /dev/null 2>&1
21744         if [ $? -eq 0 ]; then
21745                 return 1
21746         fi
21747
21748         lfs ladvise -a willread $file 2>&1 |
21749                 grep "Inappropriate ioctl for device" > /dev/null
21750         if [ $? -eq 0 ]; then
21751                 return 0
21752         fi
21753         return 1
21754 }
21755
21756 percent() {
21757         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21758 }
21759
21760 # run a random read IO workload
21761 # usage: random_read_iops <filename> <filesize> <iosize>
21762 random_read_iops() {
21763         local file=$1
21764         local fsize=$2
21765         local iosize=${3:-4096}
21766
21767         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21768                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21769 }
21770
21771 drop_file_oss_cache() {
21772         local file="$1"
21773         local nodes="$2"
21774
21775         $LFS ladvise -a dontneed $file 2>/dev/null ||
21776                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21777 }
21778
21779 ladvise_willread_performance()
21780 {
21781         local repeat=10
21782         local average_origin=0
21783         local average_cache=0
21784         local average_ladvise=0
21785
21786         for ((i = 1; i <= $repeat; i++)); do
21787                 echo "Iter $i/$repeat: reading without willread hint"
21788                 cancel_lru_locks osc
21789                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21790                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21791                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21792                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21793
21794                 cancel_lru_locks osc
21795                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21796                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21797                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21798
21799                 cancel_lru_locks osc
21800                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21801                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21802                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21803                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21804                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21805         done
21806         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21807         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21808         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21809
21810         speedup_cache=$(percent $average_cache $average_origin)
21811         speedup_ladvise=$(percent $average_ladvise $average_origin)
21812
21813         echo "Average uncached read: $average_origin"
21814         echo "Average speedup with OSS cached read: " \
21815                 "$average_cache = +$speedup_cache%"
21816         echo "Average speedup with ladvise willread: " \
21817                 "$average_ladvise = +$speedup_ladvise%"
21818
21819         local lowest_speedup=20
21820         if (( ${average_cache%.*} < $lowest_speedup )); then
21821                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21822                      " got $average_cache%. Skipping ladvise willread check."
21823                 return 0
21824         fi
21825
21826         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21827         # it is still good to run until then to exercise 'ladvise willread'
21828         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21829                 [ "$ost1_FSTYPE" = "zfs" ] &&
21830                 echo "osd-zfs does not support dontneed or drop_caches" &&
21831                 return 0
21832
21833         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21834         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21835                 error_not_in_vm "Speedup with willread is less than " \
21836                         "$lowest_speedup%, got $average_ladvise%"
21837 }
21838
21839 test_255a() {
21840         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21841                 skip "lustre < 2.8.54 does not support ladvise "
21842         remote_ost_nodsh && skip "remote OST with nodsh"
21843
21844         stack_trap "rm -f $DIR/$tfile"
21845         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21846
21847         ladvise_no_type willread $DIR/$tfile &&
21848                 skip "willread ladvise is not supported"
21849
21850         ladvise_no_ioctl $DIR/$tfile &&
21851                 skip "ladvise ioctl is not supported"
21852
21853         local size_mb=100
21854         local size=$((size_mb * 1048576))
21855         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21856                 error "dd to $DIR/$tfile failed"
21857
21858         lfs ladvise -a willread $DIR/$tfile ||
21859                 error "Ladvise failed with no range argument"
21860
21861         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21862                 error "Ladvise failed with no -l or -e argument"
21863
21864         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21865                 error "Ladvise failed with only -e argument"
21866
21867         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21868                 error "Ladvise failed with only -l argument"
21869
21870         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21871                 error "End offset should not be smaller than start offset"
21872
21873         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21874                 error "End offset should not be equal to start offset"
21875
21876         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21877                 error "Ladvise failed with overflowing -s argument"
21878
21879         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21880                 error "Ladvise failed with overflowing -e argument"
21881
21882         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21883                 error "Ladvise failed with overflowing -l argument"
21884
21885         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21886                 error "Ladvise succeeded with conflicting -l and -e arguments"
21887
21888         echo "Synchronous ladvise should wait"
21889         local delay=4
21890 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21891         do_nodes $(comma_list $(osts_nodes)) \
21892                 $LCTL set_param fail_val=$delay fail_loc=0x237
21893
21894         local start_ts=$SECONDS
21895         lfs ladvise -a willread $DIR/$tfile ||
21896                 error "Ladvise failed with no range argument"
21897         local end_ts=$SECONDS
21898         local inteval_ts=$((end_ts - start_ts))
21899
21900         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21901                 error "Synchronous advice didn't wait reply"
21902         fi
21903
21904         echo "Asynchronous ladvise shouldn't wait"
21905         local start_ts=$SECONDS
21906         lfs ladvise -a willread -b $DIR/$tfile ||
21907                 error "Ladvise failed with no range argument"
21908         local end_ts=$SECONDS
21909         local inteval_ts=$((end_ts - start_ts))
21910
21911         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21912                 error "Asynchronous advice blocked"
21913         fi
21914
21915         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21916         ladvise_willread_performance
21917 }
21918 run_test 255a "check 'lfs ladvise -a willread'"
21919
21920 facet_meminfo() {
21921         local facet=$1
21922         local info=$2
21923
21924         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21925 }
21926
21927 test_255b() {
21928         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21929                 skip "lustre < 2.8.54 does not support ladvise "
21930         remote_ost_nodsh && skip "remote OST with nodsh"
21931
21932         stack_trap "rm -f $DIR/$tfile"
21933         lfs setstripe -c 1 -i 0 $DIR/$tfile
21934
21935         ladvise_no_type dontneed $DIR/$tfile &&
21936                 skip "dontneed ladvise is not supported"
21937
21938         ladvise_no_ioctl $DIR/$tfile &&
21939                 skip "ladvise ioctl is not supported"
21940
21941         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21942                 [ "$ost1_FSTYPE" = "zfs" ] &&
21943                 skip "zfs-osd does not support 'ladvise dontneed'"
21944
21945         local size_mb=100
21946         local size=$((size_mb * 1048576))
21947         # In order to prevent disturbance of other processes, only check 3/4
21948         # of the memory usage
21949         local kibibytes=$((size_mb * 1024 * 3 / 4))
21950
21951         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21952                 error "dd to $DIR/$tfile failed"
21953
21954         #force write to complete before dropping OST cache & checking memory
21955         sync
21956
21957         local total=$(facet_meminfo ost1 MemTotal)
21958         echo "Total memory: $total KiB"
21959
21960         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21961         local before_read=$(facet_meminfo ost1 Cached)
21962         echo "Cache used before read: $before_read KiB"
21963
21964         lfs ladvise -a willread $DIR/$tfile ||
21965                 error "Ladvise willread failed"
21966         local after_read=$(facet_meminfo ost1 Cached)
21967         echo "Cache used after read: $after_read KiB"
21968
21969         lfs ladvise -a dontneed $DIR/$tfile ||
21970                 error "Ladvise dontneed again failed"
21971         local no_read=$(facet_meminfo ost1 Cached)
21972         echo "Cache used after dontneed ladvise: $no_read KiB"
21973
21974         if [ $total -lt $((before_read + kibibytes)) ]; then
21975                 echo "Memory is too small, abort checking"
21976                 return 0
21977         fi
21978
21979         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21980                 error "Ladvise willread should use more memory" \
21981                         "than $kibibytes KiB"
21982         fi
21983
21984         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21985                 error "Ladvise dontneed should release more memory" \
21986                         "than $kibibytes KiB"
21987         fi
21988 }
21989 run_test 255b "check 'lfs ladvise -a dontneed'"
21990
21991 test_255c() {
21992         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21993                 skip "lustre < 2.10.50 does not support lockahead"
21994
21995         local ost1_imp=$(get_osc_import_name client ost1)
21996         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21997                          cut -d'.' -f2)
21998         local count
21999         local new_count
22000         local difference
22001         local i
22002         local rc
22003
22004         test_mkdir -p $DIR/$tdir
22005         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22006
22007         #test 10 returns only success/failure
22008         i=10
22009         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22010         rc=$?
22011         if [ $rc -eq 255 ]; then
22012                 error "Ladvise test${i} failed, ${rc}"
22013         fi
22014
22015         #test 11 counts lock enqueue requests, all others count new locks
22016         i=11
22017         count=$(do_facet ost1 \
22018                 $LCTL get_param -n ost.OSS.ost.stats)
22019         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22020
22021         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22022         rc=$?
22023         if [ $rc -eq 255 ]; then
22024                 error "Ladvise test${i} failed, ${rc}"
22025         fi
22026
22027         new_count=$(do_facet ost1 \
22028                 $LCTL get_param -n ost.OSS.ost.stats)
22029         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22030                    awk '{ print $2 }')
22031
22032         difference="$((new_count - count))"
22033         if [ $difference -ne $rc ]; then
22034                 error "Ladvise test${i}, bad enqueue count, returned " \
22035                       "${rc}, actual ${difference}"
22036         fi
22037
22038         for i in $(seq 12 21); do
22039                 # If we do not do this, we run the risk of having too many
22040                 # locks and starting lock cancellation while we are checking
22041                 # lock counts.
22042                 cancel_lru_locks osc
22043
22044                 count=$($LCTL get_param -n \
22045                        ldlm.namespaces.$imp_name.lock_unused_count)
22046
22047                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22048                 rc=$?
22049                 if [ $rc -eq 255 ]; then
22050                         error "Ladvise test ${i} failed, ${rc}"
22051                 fi
22052
22053                 new_count=$($LCTL get_param -n \
22054                        ldlm.namespaces.$imp_name.lock_unused_count)
22055                 difference="$((new_count - count))"
22056
22057                 # Test 15 output is divided by 100 to map down to valid return
22058                 if [ $i -eq 15 ]; then
22059                         rc="$((rc * 100))"
22060                 fi
22061
22062                 if [ $difference -ne $rc ]; then
22063                         error "Ladvise test ${i}, bad lock count, returned " \
22064                               "${rc}, actual ${difference}"
22065                 fi
22066         done
22067
22068         #test 22 returns only success/failure
22069         i=22
22070         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22071         rc=$?
22072         if [ $rc -eq 255 ]; then
22073                 error "Ladvise test${i} failed, ${rc}"
22074         fi
22075 }
22076 run_test 255c "suite of ladvise lockahead tests"
22077
22078 test_256() {
22079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22080         remote_mds_nodsh && skip "remote MDS with nodsh"
22081         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22082         changelog_users $SINGLEMDS | grep "^cl" &&
22083                 skip "active changelog user"
22084
22085         local cl_user
22086         local cat_sl
22087         local mdt_dev
22088
22089         mdt_dev=$(facet_device $SINGLEMDS)
22090         echo $mdt_dev
22091
22092         changelog_register || error "changelog_register failed"
22093
22094         rm -rf $DIR/$tdir
22095         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22096
22097         changelog_clear 0 || error "changelog_clear failed"
22098
22099         # change something
22100         touch $DIR/$tdir/{1..10}
22101
22102         # stop the MDT
22103         stop $SINGLEMDS || error "Fail to stop MDT"
22104
22105         # remount the MDT
22106         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22107                 error "Fail to start MDT"
22108
22109         #after mount new plainllog is used
22110         touch $DIR/$tdir/{11..19}
22111         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22112         stack_trap "rm -f $tmpfile"
22113         cat_sl=$(do_facet $SINGLEMDS "sync; \
22114                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22115                  llog_reader $tmpfile | grep -c type=1064553b")
22116         do_facet $SINGLEMDS llog_reader $tmpfile
22117
22118         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22119
22120         changelog_clear 0 || error "changelog_clear failed"
22121
22122         cat_sl=$(do_facet $SINGLEMDS "sync; \
22123                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22124                  llog_reader $tmpfile | grep -c type=1064553b")
22125
22126         if (( cat_sl == 2 )); then
22127                 error "Empty plain llog was not deleted from changelog catalog"
22128         elif (( cat_sl != 1 )); then
22129                 error "Active plain llog shouldn't be deleted from catalog"
22130         fi
22131 }
22132 run_test 256 "Check llog delete for empty and not full state"
22133
22134 test_257() {
22135         remote_mds_nodsh && skip "remote MDS with nodsh"
22136         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22137                 skip "Need MDS version at least 2.8.55"
22138
22139         test_mkdir $DIR/$tdir
22140
22141         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22142                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22143         stat $DIR/$tdir
22144
22145 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22146         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22147         local facet=mds$((mdtidx + 1))
22148         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22149         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22150
22151         stop $facet || error "stop MDS failed"
22152         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22153                 error "start MDS fail"
22154         wait_recovery_complete $facet
22155 }
22156 run_test 257 "xattr locks are not lost"
22157
22158 # Verify we take the i_mutex when security requires it
22159 test_258a() {
22160 #define OBD_FAIL_IMUTEX_SEC 0x141c
22161         $LCTL set_param fail_loc=0x141c
22162         touch $DIR/$tfile
22163         chmod u+s $DIR/$tfile
22164         chmod a+rwx $DIR/$tfile
22165         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22166         RC=$?
22167         if [ $RC -ne 0 ]; then
22168                 error "error, failed to take i_mutex, rc=$?"
22169         fi
22170         rm -f $DIR/$tfile
22171 }
22172 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22173
22174 # Verify we do NOT take the i_mutex in the normal case
22175 test_258b() {
22176 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22177         $LCTL set_param fail_loc=0x141d
22178         touch $DIR/$tfile
22179         chmod a+rwx $DIR
22180         chmod a+rw $DIR/$tfile
22181         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22182         RC=$?
22183         if [ $RC -ne 0 ]; then
22184                 error "error, took i_mutex unnecessarily, rc=$?"
22185         fi
22186         rm -f $DIR/$tfile
22187
22188 }
22189 run_test 258b "verify i_mutex security behavior"
22190
22191 test_259() {
22192         local file=$DIR/$tfile
22193         local before
22194         local after
22195
22196         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22197
22198         stack_trap "rm -f $file" EXIT
22199
22200         wait_delete_completed
22201         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22202         echo "before: $before"
22203
22204         $LFS setstripe -i 0 -c 1 $file
22205         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22206         sync_all_data
22207         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22208         echo "after write: $after"
22209
22210 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22211         do_facet ost1 $LCTL set_param fail_loc=0x2301
22212         $TRUNCATE $file 0
22213         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22214         echo "after truncate: $after"
22215
22216         stop ost1
22217         do_facet ost1 $LCTL set_param fail_loc=0
22218         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22219         sleep 2
22220         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22221         echo "after restart: $after"
22222         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22223                 error "missing truncate?"
22224
22225         return 0
22226 }
22227 run_test 259 "crash at delayed truncate"
22228
22229 test_260() {
22230 #define OBD_FAIL_MDC_CLOSE               0x806
22231         $LCTL set_param fail_loc=0x80000806
22232         touch $DIR/$tfile
22233
22234 }
22235 run_test 260 "Check mdc_close fail"
22236
22237 ### Data-on-MDT sanity tests ###
22238 test_270a() {
22239         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22240                 skip "Need MDS version at least 2.10.55 for DoM"
22241
22242         # create DoM file
22243         local dom=$DIR/$tdir/dom_file
22244         local tmp=$DIR/$tdir/tmp_file
22245
22246         mkdir_on_mdt0 $DIR/$tdir
22247
22248         # basic checks for DoM component creation
22249         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22250                 error "Can set MDT layout to non-first entry"
22251
22252         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22253                 error "Can define multiple entries as MDT layout"
22254
22255         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22256
22257         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22258         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22259         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22260
22261         local mdtidx=$($LFS getstripe -m $dom)
22262         local mdtname=MDT$(printf %04x $mdtidx)
22263         local facet=mds$((mdtidx + 1))
22264         local space_check=1
22265
22266         # Skip free space checks with ZFS
22267         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22268
22269         # write
22270         sync
22271         local size_tmp=$((65536 * 3))
22272         local mdtfree1=$(do_facet $facet \
22273                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22274
22275         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22276         # check also direct IO along write
22277         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22278         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22279         sync
22280         cmp $tmp $dom || error "file data is different"
22281         [ $(stat -c%s $dom) == $size_tmp ] ||
22282                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22283         if [ $space_check == 1 ]; then
22284                 local mdtfree2=$(do_facet $facet \
22285                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22286
22287                 # increase in usage from by $size_tmp
22288                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22289                         error "MDT free space wrong after write: " \
22290                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22291         fi
22292
22293         # truncate
22294         local size_dom=10000
22295
22296         $TRUNCATE $dom $size_dom
22297         [ $(stat -c%s $dom) == $size_dom ] ||
22298                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22299         if [ $space_check == 1 ]; then
22300                 mdtfree1=$(do_facet $facet \
22301                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22302                 # decrease in usage from $size_tmp to new $size_dom
22303                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22304                   $(((size_tmp - size_dom) / 1024)) ] ||
22305                         error "MDT free space is wrong after truncate: " \
22306                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22307         fi
22308
22309         # append
22310         cat $tmp >> $dom
22311         sync
22312         size_dom=$((size_dom + size_tmp))
22313         [ $(stat -c%s $dom) == $size_dom ] ||
22314                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22315         if [ $space_check == 1 ]; then
22316                 mdtfree2=$(do_facet $facet \
22317                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22318                 # increase in usage by $size_tmp from previous
22319                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22320                         error "MDT free space is wrong after append: " \
22321                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22322         fi
22323
22324         # delete
22325         rm $dom
22326         if [ $space_check == 1 ]; then
22327                 mdtfree1=$(do_facet $facet \
22328                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22329                 # decrease in usage by $size_dom from previous
22330                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22331                         error "MDT free space is wrong after removal: " \
22332                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22333         fi
22334
22335         # combined striping
22336         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22337                 error "Can't create DoM + OST striping"
22338
22339         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22340         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22341         # check also direct IO along write
22342         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22343         sync
22344         cmp $tmp $dom || error "file data is different"
22345         [ $(stat -c%s $dom) == $size_tmp ] ||
22346                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22347         rm $dom $tmp
22348
22349         return 0
22350 }
22351 run_test 270a "DoM: basic functionality tests"
22352
22353 test_270b() {
22354         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22355                 skip "Need MDS version at least 2.10.55"
22356
22357         local dom=$DIR/$tdir/dom_file
22358         local max_size=1048576
22359
22360         mkdir -p $DIR/$tdir
22361         $LFS setstripe -E $max_size -L mdt $dom
22362
22363         # truncate over the limit
22364         $TRUNCATE $dom $(($max_size + 1)) &&
22365                 error "successful truncate over the maximum size"
22366         # write over the limit
22367         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22368                 error "successful write over the maximum size"
22369         # append over the limit
22370         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22371         echo "12345" >> $dom && error "successful append over the maximum size"
22372         rm $dom
22373
22374         return 0
22375 }
22376 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22377
22378 test_270c() {
22379         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22380                 skip "Need MDS version at least 2.10.55"
22381
22382         mkdir -p $DIR/$tdir
22383         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22384
22385         # check files inherit DoM EA
22386         touch $DIR/$tdir/first
22387         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22388                 error "bad pattern"
22389         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22390                 error "bad stripe count"
22391         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22392                 error "bad stripe size"
22393
22394         # check directory inherits DoM EA and uses it as default
22395         mkdir $DIR/$tdir/subdir
22396         touch $DIR/$tdir/subdir/second
22397         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22398                 error "bad pattern in sub-directory"
22399         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22400                 error "bad stripe count in sub-directory"
22401         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22402                 error "bad stripe size in sub-directory"
22403         return 0
22404 }
22405 run_test 270c "DoM: DoM EA inheritance tests"
22406
22407 test_270d() {
22408         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22409                 skip "Need MDS version at least 2.10.55"
22410
22411         mkdir -p $DIR/$tdir
22412         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22413
22414         # inherit default DoM striping
22415         mkdir $DIR/$tdir/subdir
22416         touch $DIR/$tdir/subdir/f1
22417
22418         # change default directory striping
22419         $LFS setstripe -c 1 $DIR/$tdir/subdir
22420         touch $DIR/$tdir/subdir/f2
22421         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22422                 error "wrong default striping in file 2"
22423         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22424                 error "bad pattern in file 2"
22425         return 0
22426 }
22427 run_test 270d "DoM: change striping from DoM to RAID0"
22428
22429 test_270e() {
22430         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22431                 skip "Need MDS version at least 2.10.55"
22432
22433         mkdir -p $DIR/$tdir/dom
22434         mkdir -p $DIR/$tdir/norm
22435         DOMFILES=20
22436         NORMFILES=10
22437         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22438         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22439
22440         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22441         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22442
22443         # find DoM files by layout
22444         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22445         [ $NUM -eq  $DOMFILES ] ||
22446                 error "lfs find -L: found $NUM, expected $DOMFILES"
22447         echo "Test 1: lfs find 20 DOM files by layout: OK"
22448
22449         # there should be 1 dir with default DOM striping
22450         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22451         [ $NUM -eq  1 ] ||
22452                 error "lfs find -L: found $NUM, expected 1 dir"
22453         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22454
22455         # find DoM files by stripe size
22456         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22457         [ $NUM -eq  $DOMFILES ] ||
22458                 error "lfs find -S: found $NUM, expected $DOMFILES"
22459         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22460
22461         # find files by stripe offset except DoM files
22462         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22463         [ $NUM -eq  $NORMFILES ] ||
22464                 error "lfs find -i: found $NUM, expected $NORMFILES"
22465         echo "Test 5: lfs find no DOM files by stripe index: OK"
22466         return 0
22467 }
22468 run_test 270e "DoM: lfs find with DoM files test"
22469
22470 test_270f() {
22471         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22472                 skip "Need MDS version at least 2.10.55"
22473
22474         local mdtname=${FSNAME}-MDT0000-mdtlov
22475         local dom=$DIR/$tdir/dom_file
22476         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22477                                                 lod.$mdtname.dom_stripesize)
22478         local dom_limit=131072
22479
22480         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22481         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22482                                                 lod.$mdtname.dom_stripesize)
22483         [ ${dom_limit} -eq ${dom_current} ] ||
22484                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22485
22486         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22487         $LFS setstripe -d $DIR/$tdir
22488         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22489                 error "Can't set directory default striping"
22490
22491         # exceed maximum stripe size
22492         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22493                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22494         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22495                 error "Able to create DoM component size more than LOD limit"
22496
22497         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22498         dom_current=$(do_facet mds1 $LCTL get_param -n \
22499                                                 lod.$mdtname.dom_stripesize)
22500         [ 0 -eq ${dom_current} ] ||
22501                 error "Can't set zero DoM stripe limit"
22502         rm $dom
22503
22504         # attempt to create DoM file on server with disabled DoM should
22505         # remove DoM entry from layout and be succeed
22506         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22507                 error "Can't create DoM file (DoM is disabled)"
22508         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22509                 error "File has DoM component while DoM is disabled"
22510         rm $dom
22511
22512         # attempt to create DoM file with only DoM stripe should return error
22513         $LFS setstripe -E $dom_limit -L mdt $dom &&
22514                 error "Able to create DoM-only file while DoM is disabled"
22515
22516         # too low values to be aligned with smallest stripe size 64K
22517         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22518         dom_current=$(do_facet mds1 $LCTL get_param -n \
22519                                                 lod.$mdtname.dom_stripesize)
22520         [ 30000 -eq ${dom_current} ] &&
22521                 error "Can set too small DoM stripe limit"
22522
22523         # 64K is a minimal stripe size in Lustre, expect limit of that size
22524         [ 65536 -eq ${dom_current} ] ||
22525                 error "Limit is not set to 64K but ${dom_current}"
22526
22527         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22528         dom_current=$(do_facet mds1 $LCTL get_param -n \
22529                                                 lod.$mdtname.dom_stripesize)
22530         echo $dom_current
22531         [ 2147483648 -eq ${dom_current} ] &&
22532                 error "Can set too large DoM stripe limit"
22533
22534         do_facet mds1 $LCTL set_param -n \
22535                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22536         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22537                 error "Can't create DoM component size after limit change"
22538         do_facet mds1 $LCTL set_param -n \
22539                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22540         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22541                 error "Can't create DoM file after limit decrease"
22542         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22543                 error "Can create big DoM component after limit decrease"
22544         touch ${dom}_def ||
22545                 error "Can't create file with old default layout"
22546
22547         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22548         return 0
22549 }
22550 run_test 270f "DoM: maximum DoM stripe size checks"
22551
22552 test_270g() {
22553         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22554                 skip "Need MDS version at least 2.13.52"
22555         local dom=$DIR/$tdir/$tfile
22556
22557         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22558         local lodname=${FSNAME}-MDT0000-mdtlov
22559
22560         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22561         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22562         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22563         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22564
22565         local dom_limit=1024
22566         local dom_threshold="50%"
22567
22568         $LFS setstripe -d $DIR/$tdir
22569         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22570                 error "Can't set directory default striping"
22571
22572         do_facet mds1 $LCTL set_param -n \
22573                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22574         # set 0 threshold and create DOM file to change tunable stripesize
22575         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22576         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22577                 error "Failed to create $dom file"
22578         # now tunable dom_cur_stripesize should reach maximum
22579         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22580                                         lod.${lodname}.dom_stripesize_cur_kb)
22581         [[ $dom_current == $dom_limit ]] ||
22582                 error "Current DOM stripesize is not maximum"
22583         rm $dom
22584
22585         # set threshold for further tests
22586         do_facet mds1 $LCTL set_param -n \
22587                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22588         echo "DOM threshold is $dom_threshold free space"
22589         local dom_def
22590         local dom_set
22591         # Spoof bfree to exceed threshold
22592         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22593         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22594         for spfree in 40 20 0 15 30 55; do
22595                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22596                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22597                         error "Failed to create $dom file"
22598                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22599                                         lod.${lodname}.dom_stripesize_cur_kb)
22600                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22601                 [[ $dom_def != $dom_current ]] ||
22602                         error "Default stripe size was not changed"
22603                 if (( spfree > 0 )) ; then
22604                         dom_set=$($LFS getstripe -S $dom)
22605                         (( dom_set == dom_def * 1024 )) ||
22606                                 error "DOM component size is still old"
22607                 else
22608                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22609                                 error "DoM component is set with no free space"
22610                 fi
22611                 rm $dom
22612                 dom_current=$dom_def
22613         done
22614 }
22615 run_test 270g "DoM: default DoM stripe size depends on free space"
22616
22617 test_270h() {
22618         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22619                 skip "Need MDS version at least 2.13.53"
22620
22621         local mdtname=${FSNAME}-MDT0000-mdtlov
22622         local dom=$DIR/$tdir/$tfile
22623         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22624
22625         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22626         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22627
22628         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22629         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22630                 error "can't create OST file"
22631         # mirrored file with DOM entry in the second mirror
22632         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22633                 error "can't create mirror with DoM component"
22634
22635         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22636
22637         # DOM component in the middle and has other enries in the same mirror,
22638         # should succeed but lost DoM component
22639         $LFS setstripe --copy=${dom}_1 $dom ||
22640                 error "Can't create file from OST|DOM mirror layout"
22641         # check new file has no DoM layout after all
22642         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22643                 error "File has DoM component while DoM is disabled"
22644 }
22645 run_test 270h "DoM: DoM stripe removal when disabled on server"
22646
22647 test_270i() {
22648         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22649                 skip "Need MDS version at least 2.14.54"
22650
22651         mkdir $DIR/$tdir
22652         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22653                 error "setstripe should fail" || true
22654 }
22655 run_test 270i "DoM: setting invalid DoM striping should fail"
22656
22657 test_271a() {
22658         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22659                 skip "Need MDS version at least 2.10.55"
22660
22661         local dom=$DIR/$tdir/dom
22662
22663         mkdir -p $DIR/$tdir
22664
22665         $LFS setstripe -E 1024K -L mdt $dom
22666
22667         lctl set_param -n mdc.*.stats=clear
22668         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22669         cat $dom > /dev/null
22670         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22671         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22672         ls $dom
22673         rm -f $dom
22674 }
22675 run_test 271a "DoM: data is cached for read after write"
22676
22677 test_271b() {
22678         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22679                 skip "Need MDS version at least 2.10.55"
22680
22681         local dom=$DIR/$tdir/dom
22682
22683         mkdir -p $DIR/$tdir
22684
22685         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22686
22687         lctl set_param -n mdc.*.stats=clear
22688         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22689         cancel_lru_locks mdc
22690         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22691         # second stat to check size is cached on client
22692         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22693         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22694         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22695         rm -f $dom
22696 }
22697 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22698
22699 test_271ba() {
22700         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22701                 skip "Need MDS version at least 2.10.55"
22702
22703         local dom=$DIR/$tdir/dom
22704
22705         mkdir -p $DIR/$tdir
22706
22707         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22708
22709         lctl set_param -n mdc.*.stats=clear
22710         lctl set_param -n osc.*.stats=clear
22711         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22712         cancel_lru_locks mdc
22713         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22714         # second stat to check size is cached on client
22715         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22716         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22717         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22718         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22719         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22720         rm -f $dom
22721 }
22722 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22723
22724
22725 get_mdc_stats() {
22726         local mdtidx=$1
22727         local param=$2
22728         local mdt=MDT$(printf %04x $mdtidx)
22729
22730         if [ -z $param ]; then
22731                 lctl get_param -n mdc.*$mdt*.stats
22732         else
22733                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22734         fi
22735 }
22736
22737 test_271c() {
22738         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22739                 skip "Need MDS version at least 2.10.55"
22740
22741         local dom=$DIR/$tdir/dom
22742
22743         mkdir -p $DIR/$tdir
22744
22745         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22746
22747         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22748         local facet=mds$((mdtidx + 1))
22749
22750         cancel_lru_locks mdc
22751         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22752         createmany -o $dom 1000
22753         lctl set_param -n mdc.*.stats=clear
22754         smalliomany -w $dom 1000 200
22755         get_mdc_stats $mdtidx
22756         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22757         # Each file has 1 open, 1 IO enqueues, total 2000
22758         # but now we have also +1 getxattr for security.capability, total 3000
22759         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22760         unlinkmany $dom 1000
22761
22762         cancel_lru_locks mdc
22763         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22764         createmany -o $dom 1000
22765         lctl set_param -n mdc.*.stats=clear
22766         smalliomany -w $dom 1000 200
22767         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22768         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22769         # for OPEN and IO lock.
22770         [ $((enq - enq_2)) -ge 1000 ] ||
22771                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22772         unlinkmany $dom 1000
22773         return 0
22774 }
22775 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22776
22777 cleanup_271def_tests() {
22778         trap 0
22779         rm -f $1
22780 }
22781
22782 test_271d() {
22783         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22784                 skip "Need MDS version at least 2.10.57"
22785
22786         local dom=$DIR/$tdir/dom
22787         local tmp=$TMP/$tfile
22788         trap "cleanup_271def_tests $tmp" EXIT
22789
22790         mkdir -p $DIR/$tdir
22791
22792         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22793
22794         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22795
22796         cancel_lru_locks mdc
22797         dd if=/dev/urandom of=$tmp bs=1000 count=1
22798         dd if=$tmp of=$dom bs=1000 count=1
22799         cancel_lru_locks mdc
22800
22801         cat /etc/hosts >> $tmp
22802         lctl set_param -n mdc.*.stats=clear
22803
22804         # append data to the same file it should update local page
22805         echo "Append to the same page"
22806         cat /etc/hosts >> $dom
22807         local num=$(get_mdc_stats $mdtidx ost_read)
22808         local ra=$(get_mdc_stats $mdtidx req_active)
22809         local rw=$(get_mdc_stats $mdtidx req_waittime)
22810
22811         [ -z $num ] || error "$num READ RPC occured"
22812         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22813         echo "... DONE"
22814
22815         # compare content
22816         cmp $tmp $dom || error "file miscompare"
22817
22818         cancel_lru_locks mdc
22819         lctl set_param -n mdc.*.stats=clear
22820
22821         echo "Open and read file"
22822         cat $dom > /dev/null
22823         local num=$(get_mdc_stats $mdtidx ost_read)
22824         local ra=$(get_mdc_stats $mdtidx req_active)
22825         local rw=$(get_mdc_stats $mdtidx req_waittime)
22826
22827         [ -z $num ] || error "$num READ RPC occured"
22828         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22829         echo "... DONE"
22830
22831         # compare content
22832         cmp $tmp $dom || error "file miscompare"
22833
22834         return 0
22835 }
22836 run_test 271d "DoM: read on open (1K file in reply buffer)"
22837
22838 test_271f() {
22839         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22840                 skip "Need MDS version at least 2.10.57"
22841
22842         local dom=$DIR/$tdir/dom
22843         local tmp=$TMP/$tfile
22844         trap "cleanup_271def_tests $tmp" EXIT
22845
22846         mkdir -p $DIR/$tdir
22847
22848         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22849
22850         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22851
22852         cancel_lru_locks mdc
22853         dd if=/dev/urandom of=$tmp bs=265000 count=1
22854         dd if=$tmp of=$dom bs=265000 count=1
22855         cancel_lru_locks mdc
22856         cat /etc/hosts >> $tmp
22857         lctl set_param -n mdc.*.stats=clear
22858
22859         echo "Append to the same page"
22860         cat /etc/hosts >> $dom
22861         local num=$(get_mdc_stats $mdtidx ost_read)
22862         local ra=$(get_mdc_stats $mdtidx req_active)
22863         local rw=$(get_mdc_stats $mdtidx req_waittime)
22864
22865         [ -z $num ] || error "$num READ RPC occured"
22866         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22867         echo "... DONE"
22868
22869         # compare content
22870         cmp $tmp $dom || error "file miscompare"
22871
22872         cancel_lru_locks mdc
22873         lctl set_param -n mdc.*.stats=clear
22874
22875         echo "Open and read file"
22876         cat $dom > /dev/null
22877         local num=$(get_mdc_stats $mdtidx ost_read)
22878         local ra=$(get_mdc_stats $mdtidx req_active)
22879         local rw=$(get_mdc_stats $mdtidx req_waittime)
22880
22881         [ -z $num ] && num=0
22882         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22883         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22884         echo "... DONE"
22885
22886         # compare content
22887         cmp $tmp $dom || error "file miscompare"
22888
22889         return 0
22890 }
22891 run_test 271f "DoM: read on open (200K file and read tail)"
22892
22893 test_271g() {
22894         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22895                 skip "Skipping due to old client or server version"
22896
22897         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22898         # to get layout
22899         $CHECKSTAT -t file $DIR1/$tfile
22900
22901         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22902         MULTIOP_PID=$!
22903         sleep 1
22904         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22905         $LCTL set_param fail_loc=0x80000314
22906         rm $DIR1/$tfile || error "Unlink fails"
22907         RC=$?
22908         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22909         [ $RC -eq 0 ] || error "Failed write to stale object"
22910 }
22911 run_test 271g "Discard DoM data vs client flush race"
22912
22913 test_272a() {
22914         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22915                 skip "Need MDS version at least 2.11.50"
22916
22917         local dom=$DIR/$tdir/dom
22918         mkdir -p $DIR/$tdir
22919
22920         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22921         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22922                 error "failed to write data into $dom"
22923         local old_md5=$(md5sum $dom)
22924
22925         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22926                 error "failed to migrate to the same DoM component"
22927
22928         local new_md5=$(md5sum $dom)
22929
22930         [ "$old_md5" == "$new_md5" ] ||
22931                 error "md5sum differ: $old_md5, $new_md5"
22932
22933         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22934                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22935 }
22936 run_test 272a "DoM migration: new layout with the same DOM component"
22937
22938 test_272b() {
22939         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22940                 skip "Need MDS version at least 2.11.50"
22941
22942         local dom=$DIR/$tdir/dom
22943         mkdir -p $DIR/$tdir
22944         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22945
22946         local mdtidx=$($LFS getstripe -m $dom)
22947         local mdtname=MDT$(printf %04x $mdtidx)
22948         local facet=mds$((mdtidx + 1))
22949
22950         local mdtfree1=$(do_facet $facet \
22951                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22952         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22953                 error "failed to write data into $dom"
22954         local old_md5=$(md5sum $dom)
22955         cancel_lru_locks mdc
22956         local mdtfree1=$(do_facet $facet \
22957                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22958
22959         $LFS migrate -c2 $dom ||
22960                 error "failed to migrate to the new composite layout"
22961         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22962                 error "MDT stripe was not removed"
22963
22964         cancel_lru_locks mdc
22965         local new_md5=$(md5sum $dom)
22966         [ "$old_md5" == "$new_md5" ] ||
22967                 error "$old_md5 != $new_md5"
22968
22969         # Skip free space checks with ZFS
22970         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22971                 local mdtfree2=$(do_facet $facet \
22972                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22973                 [ $mdtfree2 -gt $mdtfree1 ] ||
22974                         error "MDT space is not freed after migration"
22975         fi
22976         return 0
22977 }
22978 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22979
22980 test_272c() {
22981         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22982                 skip "Need MDS version at least 2.11.50"
22983
22984         local dom=$DIR/$tdir/$tfile
22985         mkdir -p $DIR/$tdir
22986         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22987
22988         local mdtidx=$($LFS getstripe -m $dom)
22989         local mdtname=MDT$(printf %04x $mdtidx)
22990         local facet=mds$((mdtidx + 1))
22991
22992         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22993                 error "failed to write data into $dom"
22994         local old_md5=$(md5sum $dom)
22995         cancel_lru_locks mdc
22996         local mdtfree1=$(do_facet $facet \
22997                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22998
22999         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23000                 error "failed to migrate to the new composite layout"
23001         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23002                 error "MDT stripe was not removed"
23003
23004         cancel_lru_locks mdc
23005         local new_md5=$(md5sum $dom)
23006         [ "$old_md5" == "$new_md5" ] ||
23007                 error "$old_md5 != $new_md5"
23008
23009         # Skip free space checks with ZFS
23010         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23011                 local mdtfree2=$(do_facet $facet \
23012                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23013                 [ $mdtfree2 -gt $mdtfree1 ] ||
23014                         error "MDS space is not freed after migration"
23015         fi
23016         return 0
23017 }
23018 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23019
23020 test_272d() {
23021         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23022                 skip "Need MDS version at least 2.12.55"
23023
23024         local dom=$DIR/$tdir/$tfile
23025         mkdir -p $DIR/$tdir
23026         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23027
23028         local mdtidx=$($LFS getstripe -m $dom)
23029         local mdtname=MDT$(printf %04x $mdtidx)
23030         local facet=mds$((mdtidx + 1))
23031
23032         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23033                 error "failed to write data into $dom"
23034         local old_md5=$(md5sum $dom)
23035         cancel_lru_locks mdc
23036         local mdtfree1=$(do_facet $facet \
23037                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23038
23039         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23040                 error "failed mirroring to the new composite layout"
23041         $LFS mirror resync $dom ||
23042                 error "failed mirror resync"
23043         $LFS mirror split --mirror-id 1 -d $dom ||
23044                 error "failed mirror split"
23045
23046         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23047                 error "MDT stripe was not removed"
23048
23049         cancel_lru_locks mdc
23050         local new_md5=$(md5sum $dom)
23051         [ "$old_md5" == "$new_md5" ] ||
23052                 error "$old_md5 != $new_md5"
23053
23054         # Skip free space checks with ZFS
23055         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23056                 local mdtfree2=$(do_facet $facet \
23057                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23058                 [ $mdtfree2 -gt $mdtfree1 ] ||
23059                         error "MDS space is not freed after DOM mirror deletion"
23060         fi
23061         return 0
23062 }
23063 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23064
23065 test_272e() {
23066         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23067                 skip "Need MDS version at least 2.12.55"
23068
23069         local dom=$DIR/$tdir/$tfile
23070         mkdir -p $DIR/$tdir
23071         $LFS setstripe -c 2 $dom
23072
23073         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23074                 error "failed to write data into $dom"
23075         local old_md5=$(md5sum $dom)
23076         cancel_lru_locks
23077
23078         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23079                 error "failed mirroring to the DOM layout"
23080         $LFS mirror resync $dom ||
23081                 error "failed mirror resync"
23082         $LFS mirror split --mirror-id 1 -d $dom ||
23083                 error "failed mirror split"
23084
23085         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23086                 error "MDT stripe wasn't set"
23087
23088         cancel_lru_locks
23089         local new_md5=$(md5sum $dom)
23090         [ "$old_md5" == "$new_md5" ] ||
23091                 error "$old_md5 != $new_md5"
23092
23093         return 0
23094 }
23095 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23096
23097 test_272f() {
23098         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23099                 skip "Need MDS version at least 2.12.55"
23100
23101         local dom=$DIR/$tdir/$tfile
23102         mkdir -p $DIR/$tdir
23103         $LFS setstripe -c 2 $dom
23104
23105         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23106                 error "failed to write data into $dom"
23107         local old_md5=$(md5sum $dom)
23108         cancel_lru_locks
23109
23110         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23111                 error "failed migrating to the DOM file"
23112
23113         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23114                 error "MDT stripe wasn't set"
23115
23116         cancel_lru_locks
23117         local new_md5=$(md5sum $dom)
23118         [ "$old_md5" != "$new_md5" ] &&
23119                 error "$old_md5 != $new_md5"
23120
23121         return 0
23122 }
23123 run_test 272f "DoM migration: OST-striped file to DOM file"
23124
23125 test_273a() {
23126         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23127                 skip "Need MDS version at least 2.11.50"
23128
23129         # Layout swap cannot be done if either file has DOM component,
23130         # this will never be supported, migration should be used instead
23131
23132         local dom=$DIR/$tdir/$tfile
23133         mkdir -p $DIR/$tdir
23134
23135         $LFS setstripe -c2 ${dom}_plain
23136         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23137         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23138                 error "can swap layout with DoM component"
23139         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23140                 error "can swap layout with DoM component"
23141
23142         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23143         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23144                 error "can swap layout with DoM component"
23145         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23146                 error "can swap layout with DoM component"
23147         return 0
23148 }
23149 run_test 273a "DoM: layout swapping should fail with DOM"
23150
23151 test_273b() {
23152         mkdir -p $DIR/$tdir
23153         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23154
23155 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23156         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23157
23158         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23159 }
23160 run_test 273b "DoM: race writeback and object destroy"
23161
23162 test_275() {
23163         remote_ost_nodsh && skip "remote OST with nodsh"
23164         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23165                 skip "Need OST version >= 2.10.57"
23166
23167         local file=$DIR/$tfile
23168         local oss
23169
23170         oss=$(comma_list $(osts_nodes))
23171
23172         dd if=/dev/urandom of=$file bs=1M count=2 ||
23173                 error "failed to create a file"
23174         cancel_lru_locks osc
23175
23176         #lock 1
23177         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23178                 error "failed to read a file"
23179
23180 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23181         $LCTL set_param fail_loc=0x8000031f
23182
23183         cancel_lru_locks osc &
23184         sleep 1
23185
23186 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23187         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23188         #IO takes another lock, but matches the PENDING one
23189         #and places it to the IO RPC
23190         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23191                 error "failed to read a file with PENDING lock"
23192 }
23193 run_test 275 "Read on a canceled duplicate lock"
23194
23195 test_276() {
23196         remote_ost_nodsh && skip "remote OST with nodsh"
23197         local pid
23198
23199         do_facet ost1 "(while true; do \
23200                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23201                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23202         pid=$!
23203
23204         for LOOP in $(seq 20); do
23205                 stop ost1
23206                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23207         done
23208         kill -9 $pid
23209         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23210                 rm $TMP/sanity_276_pid"
23211 }
23212 run_test 276 "Race between mount and obd_statfs"
23213
23214 test_277() {
23215         $LCTL set_param ldlm.namespaces.*.lru_size=0
23216         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23217         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23218                         grep ^used_mb | awk '{print $2}')
23219         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23220         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23221                 oflag=direct conv=notrunc
23222         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23223                         grep ^used_mb | awk '{print $2}')
23224         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23225 }
23226 run_test 277 "Direct IO shall drop page cache"
23227
23228 test_278() {
23229         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23230         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23231         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23232                 skip "needs the same host for mdt1 mdt2" && return
23233
23234         local pid1
23235         local pid2
23236
23237 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23238         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23239         stop mds2 &
23240         pid2=$!
23241
23242         stop mds1
23243
23244         echo "Starting MDTs"
23245         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23246         wait $pid2
23247 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23248 #will return NULL
23249         do_facet mds2 $LCTL set_param fail_loc=0
23250
23251         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23252         wait_recovery_complete mds2
23253 }
23254 run_test 278 "Race starting MDS between MDTs stop/start"
23255
23256 test_280() {
23257         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23258                 skip "Need MGS version at least 2.13.52"
23259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23260         combined_mgs_mds || skip "needs combined MGS/MDT"
23261
23262         umount_client $MOUNT
23263 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23264         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23265
23266         mount_client $MOUNT &
23267         sleep 1
23268         stop mgs || error "stop mgs failed"
23269         #for a race mgs would crash
23270         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23271         # make sure we unmount client before remounting
23272         wait
23273         umount_client $MOUNT
23274         mount_client $MOUNT || error "mount client failed"
23275 }
23276 run_test 280 "Race between MGS umount and client llog processing"
23277
23278 cleanup_test_300() {
23279         trap 0
23280         umask $SAVE_UMASK
23281 }
23282 test_striped_dir() {
23283         local mdt_index=$1
23284         local stripe_count
23285         local stripe_index
23286
23287         mkdir -p $DIR/$tdir
23288
23289         SAVE_UMASK=$(umask)
23290         trap cleanup_test_300 RETURN EXIT
23291
23292         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23293                                                 $DIR/$tdir/striped_dir ||
23294                 error "set striped dir error"
23295
23296         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23297         [ "$mode" = "755" ] || error "expect 755 got $mode"
23298
23299         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23300                 error "getdirstripe failed"
23301         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23302         if [ "$stripe_count" != "2" ]; then
23303                 error "1:stripe_count is $stripe_count, expect 2"
23304         fi
23305         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23306         if [ "$stripe_count" != "2" ]; then
23307                 error "2:stripe_count is $stripe_count, expect 2"
23308         fi
23309
23310         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23311         if [ "$stripe_index" != "$mdt_index" ]; then
23312                 error "stripe_index is $stripe_index, expect $mdt_index"
23313         fi
23314
23315         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23316                 error "nlink error after create striped dir"
23317
23318         mkdir $DIR/$tdir/striped_dir/a
23319         mkdir $DIR/$tdir/striped_dir/b
23320
23321         stat $DIR/$tdir/striped_dir/a ||
23322                 error "create dir under striped dir failed"
23323         stat $DIR/$tdir/striped_dir/b ||
23324                 error "create dir under striped dir failed"
23325
23326         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23327                 error "nlink error after mkdir"
23328
23329         rmdir $DIR/$tdir/striped_dir/a
23330         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23331                 error "nlink error after rmdir"
23332
23333         rmdir $DIR/$tdir/striped_dir/b
23334         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23335                 error "nlink error after rmdir"
23336
23337         chattr +i $DIR/$tdir/striped_dir
23338         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23339                 error "immutable flags not working under striped dir!"
23340         chattr -i $DIR/$tdir/striped_dir
23341
23342         rmdir $DIR/$tdir/striped_dir ||
23343                 error "rmdir striped dir error"
23344
23345         cleanup_test_300
23346
23347         true
23348 }
23349
23350 test_300a() {
23351         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23352                 skip "skipped for lustre < 2.7.0"
23353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23354         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23355
23356         test_striped_dir 0 || error "failed on striped dir on MDT0"
23357         test_striped_dir 1 || error "failed on striped dir on MDT0"
23358 }
23359 run_test 300a "basic striped dir sanity test"
23360
23361 test_300b() {
23362         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23363                 skip "skipped for lustre < 2.7.0"
23364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23366
23367         local i
23368         local mtime1
23369         local mtime2
23370         local mtime3
23371
23372         test_mkdir $DIR/$tdir || error "mkdir fail"
23373         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23374                 error "set striped dir error"
23375         for i in {0..9}; do
23376                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23377                 sleep 1
23378                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23379                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23380                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23381                 sleep 1
23382                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23383                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23384                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23385         done
23386         true
23387 }
23388 run_test 300b "check ctime/mtime for striped dir"
23389
23390 test_300c() {
23391         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23392                 skip "skipped for lustre < 2.7.0"
23393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23394         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23395
23396         local file_count
23397
23398         mkdir_on_mdt0 $DIR/$tdir
23399         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23400                 error "set striped dir error"
23401
23402         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23403                 error "chown striped dir failed"
23404
23405         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23406                 error "create 5k files failed"
23407
23408         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23409
23410         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23411
23412         rm -rf $DIR/$tdir
23413 }
23414 run_test 300c "chown && check ls under striped directory"
23415
23416 test_300d() {
23417         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23418                 skip "skipped for lustre < 2.7.0"
23419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23420         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23421
23422         local stripe_count
23423         local file
23424
23425         mkdir -p $DIR/$tdir
23426         $LFS setstripe -c 2 $DIR/$tdir
23427
23428         #local striped directory
23429         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23430                 error "set striped dir error"
23431         #look at the directories for debug purposes
23432         ls -l $DIR/$tdir
23433         $LFS getdirstripe $DIR/$tdir
23434         ls -l $DIR/$tdir/striped_dir
23435         $LFS getdirstripe $DIR/$tdir/striped_dir
23436         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23437                 error "create 10 files failed"
23438
23439         #remote striped directory
23440         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23441                 error "set striped dir error"
23442         #look at the directories for debug purposes
23443         ls -l $DIR/$tdir
23444         $LFS getdirstripe $DIR/$tdir
23445         ls -l $DIR/$tdir/remote_striped_dir
23446         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23447         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23448                 error "create 10 files failed"
23449
23450         for file in $(find $DIR/$tdir); do
23451                 stripe_count=$($LFS getstripe -c $file)
23452                 [ $stripe_count -eq 2 ] ||
23453                         error "wrong stripe $stripe_count for $file"
23454         done
23455
23456         rm -rf $DIR/$tdir
23457 }
23458 run_test 300d "check default stripe under striped directory"
23459
23460 test_300e() {
23461         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23462                 skip "Need MDS version at least 2.7.55"
23463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23465
23466         local stripe_count
23467         local file
23468
23469         mkdir -p $DIR/$tdir
23470
23471         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23472                 error "set striped dir error"
23473
23474         touch $DIR/$tdir/striped_dir/a
23475         touch $DIR/$tdir/striped_dir/b
23476         touch $DIR/$tdir/striped_dir/c
23477
23478         mkdir $DIR/$tdir/striped_dir/dir_a
23479         mkdir $DIR/$tdir/striped_dir/dir_b
23480         mkdir $DIR/$tdir/striped_dir/dir_c
23481
23482         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23483                 error "set striped adir under striped dir error"
23484
23485         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23486                 error "set striped bdir under striped dir error"
23487
23488         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23489                 error "set striped cdir under striped dir error"
23490
23491         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23492                 error "rename dir under striped dir fails"
23493
23494         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23495                 error "rename dir under different stripes fails"
23496
23497         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23498                 error "rename file under striped dir should succeed"
23499
23500         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23501                 error "rename dir under striped dir should succeed"
23502
23503         rm -rf $DIR/$tdir
23504 }
23505 run_test 300e "check rename under striped directory"
23506
23507 test_300f() {
23508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23509         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23510         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23511                 skip "Need MDS version at least 2.7.55"
23512
23513         local stripe_count
23514         local file
23515
23516         rm -rf $DIR/$tdir
23517         mkdir -p $DIR/$tdir
23518
23519         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23520                 error "set striped dir error"
23521
23522         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23523                 error "set striped dir error"
23524
23525         touch $DIR/$tdir/striped_dir/a
23526         mkdir $DIR/$tdir/striped_dir/dir_a
23527         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23528                 error "create striped dir under striped dir fails"
23529
23530         touch $DIR/$tdir/striped_dir1/b
23531         mkdir $DIR/$tdir/striped_dir1/dir_b
23532         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23533                 error "create striped dir under striped dir fails"
23534
23535         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23536                 error "rename dir under different striped dir should fail"
23537
23538         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23539                 error "rename striped dir under diff striped dir should fail"
23540
23541         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23542                 error "rename file under diff striped dirs fails"
23543
23544         rm -rf $DIR/$tdir
23545 }
23546 run_test 300f "check rename cross striped directory"
23547
23548 test_300_check_default_striped_dir()
23549 {
23550         local dirname=$1
23551         local default_count=$2
23552         local default_index=$3
23553         local stripe_count
23554         local stripe_index
23555         local dir_stripe_index
23556         local dir
23557
23558         echo "checking $dirname $default_count $default_index"
23559         $LFS setdirstripe -D -c $default_count -i $default_index \
23560                                 -H all_char $DIR/$tdir/$dirname ||
23561                 error "set default stripe on striped dir error"
23562         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23563         [ $stripe_count -eq $default_count ] ||
23564                 error "expect $default_count get $stripe_count for $dirname"
23565
23566         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23567         [ $stripe_index -eq $default_index ] ||
23568                 error "expect $default_index get $stripe_index for $dirname"
23569
23570         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23571                                                 error "create dirs failed"
23572
23573         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23574         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23575         for dir in $(find $DIR/$tdir/$dirname/*); do
23576                 stripe_count=$($LFS getdirstripe -c $dir)
23577                 (( $stripe_count == $default_count )) ||
23578                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23579                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23580                 error "stripe count $default_count != $stripe_count for $dir"
23581
23582                 stripe_index=$($LFS getdirstripe -i $dir)
23583                 [ $default_index -eq -1 ] ||
23584                         [ $stripe_index -eq $default_index ] ||
23585                         error "$stripe_index != $default_index for $dir"
23586
23587                 #check default stripe
23588                 stripe_count=$($LFS getdirstripe -D -c $dir)
23589                 [ $stripe_count -eq $default_count ] ||
23590                 error "default count $default_count != $stripe_count for $dir"
23591
23592                 stripe_index=$($LFS getdirstripe -D -i $dir)
23593                 [ $stripe_index -eq $default_index ] ||
23594                 error "default index $default_index != $stripe_index for $dir"
23595         done
23596         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23597 }
23598
23599 test_300g() {
23600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23601         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23602                 skip "Need MDS version at least 2.7.55"
23603
23604         local dir
23605         local stripe_count
23606         local stripe_index
23607
23608         mkdir_on_mdt0 $DIR/$tdir
23609         mkdir $DIR/$tdir/normal_dir
23610
23611         #Checking when client cache stripe index
23612         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23613         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23614                 error "create striped_dir failed"
23615
23616         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23617                 error "create dir0 fails"
23618         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23619         [ $stripe_index -eq 0 ] ||
23620                 error "dir0 expect index 0 got $stripe_index"
23621
23622         mkdir $DIR/$tdir/striped_dir/dir1 ||
23623                 error "create dir1 fails"
23624         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23625         [ $stripe_index -eq 1 ] ||
23626                 error "dir1 expect index 1 got $stripe_index"
23627
23628         #check default stripe count/stripe index
23629         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23630         test_300_check_default_striped_dir normal_dir 1 0
23631         test_300_check_default_striped_dir normal_dir -1 1
23632         test_300_check_default_striped_dir normal_dir 2 -1
23633
23634         #delete default stripe information
23635         echo "delete default stripeEA"
23636         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23637                 error "set default stripe on striped dir error"
23638
23639         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23640         for dir in $(find $DIR/$tdir/normal_dir/*); do
23641                 stripe_count=$($LFS getdirstripe -c $dir)
23642                 [ $stripe_count -eq 0 ] ||
23643                         error "expect 1 get $stripe_count for $dir"
23644         done
23645 }
23646 run_test 300g "check default striped directory for normal directory"
23647
23648 test_300h() {
23649         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23650         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23651                 skip "Need MDS version at least 2.7.55"
23652
23653         local dir
23654         local stripe_count
23655
23656         mkdir $DIR/$tdir
23657         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23658                 error "set striped dir error"
23659
23660         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23661         test_300_check_default_striped_dir striped_dir 1 0
23662         test_300_check_default_striped_dir striped_dir -1 1
23663         test_300_check_default_striped_dir striped_dir 2 -1
23664
23665         #delete default stripe information
23666         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23667                 error "set default stripe on striped dir error"
23668
23669         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23670         for dir in $(find $DIR/$tdir/striped_dir/*); do
23671                 stripe_count=$($LFS getdirstripe -c $dir)
23672                 [ $stripe_count -eq 0 ] ||
23673                         error "expect 1 get $stripe_count for $dir"
23674         done
23675 }
23676 run_test 300h "check default striped directory for striped directory"
23677
23678 test_300i() {
23679         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23680         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23681         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23682                 skip "Need MDS version at least 2.7.55"
23683
23684         local stripe_count
23685         local file
23686
23687         mkdir $DIR/$tdir
23688
23689         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23690                 error "set striped dir error"
23691
23692         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23693                 error "create files under striped dir failed"
23694
23695         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23696                 error "set striped hashdir error"
23697
23698         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23699                 error "create dir0 under hash dir failed"
23700         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23701                 error "create dir1 under hash dir failed"
23702         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23703                 error "create dir2 under hash dir failed"
23704
23705         # unfortunately, we need to umount to clear dir layout cache for now
23706         # once we fully implement dir layout, we can drop this
23707         umount_client $MOUNT || error "umount failed"
23708         mount_client $MOUNT || error "mount failed"
23709
23710         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23711         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23712         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23713
23714         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23715                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23716                         error "create crush2 dir $tdir/hashdir/d3 failed"
23717                 $LFS find -H crush2 $DIR/$tdir/hashdir
23718                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23719                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23720
23721                 # mkdir with an invalid hash type (hash=fail_val) from client
23722                 # should be replaced on MDS with a valid (default) hash type
23723                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23724                 $LCTL set_param fail_loc=0x1901 fail_val=99
23725                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23726
23727                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23728                 local expect=$(do_facet mds1 \
23729                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23730                 [[ $hash == $expect ]] ||
23731                         error "d99 hash '$hash' != expected hash '$expect'"
23732         fi
23733
23734         #set the stripe to be unknown hash type on read
23735         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23736         $LCTL set_param fail_loc=0x1901 fail_val=99
23737         for ((i = 0; i < 10; i++)); do
23738                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23739                         error "stat f-$i failed"
23740                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23741         done
23742
23743         touch $DIR/$tdir/striped_dir/f0 &&
23744                 error "create under striped dir with unknown hash should fail"
23745
23746         $LCTL set_param fail_loc=0
23747
23748         umount_client $MOUNT || error "umount failed"
23749         mount_client $MOUNT || error "mount failed"
23750
23751         return 0
23752 }
23753 run_test 300i "client handle unknown hash type striped directory"
23754
23755 test_300j() {
23756         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23758         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23759                 skip "Need MDS version at least 2.7.55"
23760
23761         local stripe_count
23762         local file
23763
23764         mkdir $DIR/$tdir
23765
23766         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23767         $LCTL set_param fail_loc=0x1702
23768         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23769                 error "set striped dir error"
23770
23771         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23772                 error "create files under striped dir failed"
23773
23774         $LCTL set_param fail_loc=0
23775
23776         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23777
23778         return 0
23779 }
23780 run_test 300j "test large update record"
23781
23782 test_300k() {
23783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23784         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23785         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23786                 skip "Need MDS version at least 2.7.55"
23787
23788         # this test needs a huge transaction
23789         local kb
23790         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23791              osd*.$FSNAME-MDT0000.kbytestotal")
23792         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23793
23794         local stripe_count
23795         local file
23796
23797         mkdir $DIR/$tdir
23798
23799         #define OBD_FAIL_LARGE_STRIPE   0x1703
23800         $LCTL set_param fail_loc=0x1703
23801         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23802                 error "set striped dir error"
23803         $LCTL set_param fail_loc=0
23804
23805         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23806                 error "getstripeddir fails"
23807         rm -rf $DIR/$tdir/striped_dir ||
23808                 error "unlink striped dir fails"
23809
23810         return 0
23811 }
23812 run_test 300k "test large striped directory"
23813
23814 test_300l() {
23815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23817         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23818                 skip "Need MDS version at least 2.7.55"
23819
23820         local stripe_index
23821
23822         test_mkdir -p $DIR/$tdir/striped_dir
23823         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23824                         error "chown $RUNAS_ID failed"
23825         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23826                 error "set default striped dir failed"
23827
23828         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23829         $LCTL set_param fail_loc=0x80000158
23830         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23831
23832         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23833         [ $stripe_index -eq 1 ] ||
23834                 error "expect 1 get $stripe_index for $dir"
23835 }
23836 run_test 300l "non-root user to create dir under striped dir with stale layout"
23837
23838 test_300m() {
23839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23840         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23841         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23842                 skip "Need MDS version at least 2.7.55"
23843
23844         mkdir -p $DIR/$tdir/striped_dir
23845         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23846                 error "set default stripes dir error"
23847
23848         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23849
23850         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23851         [ $stripe_count -eq 0 ] ||
23852                         error "expect 0 get $stripe_count for a"
23853
23854         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23855                 error "set default stripes dir error"
23856
23857         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23858
23859         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23860         [ $stripe_count -eq 0 ] ||
23861                         error "expect 0 get $stripe_count for b"
23862
23863         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23864                 error "set default stripes dir error"
23865
23866         mkdir $DIR/$tdir/striped_dir/c &&
23867                 error "default stripe_index is invalid, mkdir c should fails"
23868
23869         rm -rf $DIR/$tdir || error "rmdir fails"
23870 }
23871 run_test 300m "setstriped directory on single MDT FS"
23872
23873 cleanup_300n() {
23874         local list=$(comma_list $(mdts_nodes))
23875
23876         trap 0
23877         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23878 }
23879
23880 test_300n() {
23881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23883         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23884                 skip "Need MDS version at least 2.7.55"
23885         remote_mds_nodsh && skip "remote MDS with nodsh"
23886
23887         local stripe_index
23888         local list=$(comma_list $(mdts_nodes))
23889
23890         trap cleanup_300n RETURN EXIT
23891         mkdir -p $DIR/$tdir
23892         chmod 777 $DIR/$tdir
23893         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23894                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23895                 error "create striped dir succeeds with gid=0"
23896
23897         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23898         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23899                 error "create striped dir fails with gid=-1"
23900
23901         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23902         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23903                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23904                 error "set default striped dir succeeds with gid=0"
23905
23906
23907         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23908         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23909                 error "set default striped dir fails with gid=-1"
23910
23911
23912         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23913         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23914                                         error "create test_dir fails"
23915         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23916                                         error "create test_dir1 fails"
23917         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23918                                         error "create test_dir2 fails"
23919         cleanup_300n
23920 }
23921 run_test 300n "non-root user to create dir under striped dir with default EA"
23922
23923 test_300o() {
23924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23925         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23926         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23927                 skip "Need MDS version at least 2.7.55"
23928
23929         local numfree1
23930         local numfree2
23931
23932         mkdir -p $DIR/$tdir
23933
23934         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23935         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23936         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23937                 skip "not enough free inodes $numfree1 $numfree2"
23938         fi
23939
23940         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23941         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23942         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23943                 skip "not enough free space $numfree1 $numfree2"
23944         fi
23945
23946         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23947                 error "setdirstripe fails"
23948
23949         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23950                 error "create dirs fails"
23951
23952         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23953         ls $DIR/$tdir/striped_dir > /dev/null ||
23954                 error "ls striped dir fails"
23955         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23956                 error "unlink big striped dir fails"
23957 }
23958 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23959
23960 test_300p() {
23961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23962         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23963         remote_mds_nodsh && skip "remote MDS with nodsh"
23964
23965         mkdir_on_mdt0 $DIR/$tdir
23966
23967         #define OBD_FAIL_OUT_ENOSPC     0x1704
23968         do_facet mds2 lctl set_param fail_loc=0x80001704
23969         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23970                  && error "create striped directory should fail"
23971
23972         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23973
23974         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23975         true
23976 }
23977 run_test 300p "create striped directory without space"
23978
23979 test_300q() {
23980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23981         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23982
23983         local fd=$(free_fd)
23984         local cmd="exec $fd<$tdir"
23985         cd $DIR
23986         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23987         eval $cmd
23988         cmd="exec $fd<&-"
23989         trap "eval $cmd" EXIT
23990         cd $tdir || error "cd $tdir fails"
23991         rmdir  ../$tdir || error "rmdir $tdir fails"
23992         mkdir local_dir && error "create dir succeeds"
23993         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23994         eval $cmd
23995         return 0
23996 }
23997 run_test 300q "create remote directory under orphan directory"
23998
23999 test_300r() {
24000         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24001                 skip "Need MDS version at least 2.7.55" && return
24002         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24003
24004         mkdir $DIR/$tdir
24005
24006         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24007                 error "set striped dir error"
24008
24009         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24010                 error "getstripeddir fails"
24011
24012         local stripe_count
24013         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24014                       awk '/lmv_stripe_count:/ { print $2 }')
24015
24016         [ $MDSCOUNT -ne $stripe_count ] &&
24017                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24018
24019         rm -rf $DIR/$tdir/striped_dir ||
24020                 error "unlink striped dir fails"
24021 }
24022 run_test 300r "test -1 striped directory"
24023
24024 test_300s_helper() {
24025         local count=$1
24026
24027         local stripe_dir=$DIR/$tdir/striped_dir.$count
24028
24029         $LFS mkdir -c $count $stripe_dir ||
24030                 error "lfs mkdir -c error"
24031
24032         $LFS getdirstripe $stripe_dir ||
24033                 error "lfs getdirstripe fails"
24034
24035         local stripe_count
24036         stripe_count=$($LFS getdirstripe $stripe_dir |
24037                       awk '/lmv_stripe_count:/ { print $2 }')
24038
24039         [ $count -ne $stripe_count ] &&
24040                 error_noexit "bad stripe count $stripe_count expected $count"
24041
24042         local dupe_stripes
24043         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24044                 awk '/0x/ {count[$1] += 1}; END {
24045                         for (idx in count) {
24046                                 if (count[idx]>1) {
24047                                         print "index " idx " count " count[idx]
24048                                 }
24049                         }
24050                 }')
24051
24052         if [[ -n "$dupe_stripes" ]] ; then
24053                 lfs getdirstripe $stripe_dir
24054                 error_noexit "Dupe MDT above: $dupe_stripes "
24055         fi
24056
24057         rm -rf $stripe_dir ||
24058                 error_noexit "unlink $stripe_dir fails"
24059 }
24060
24061 test_300s() {
24062         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24063                 skip "Need MDS version at least 2.7.55" && return
24064         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24065
24066         mkdir $DIR/$tdir
24067         for count in $(seq 2 $MDSCOUNT); do
24068                 test_300s_helper $count
24069         done
24070 }
24071 run_test 300s "test lfs mkdir -c without -i"
24072
24073 test_300t() {
24074         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24075                 skip "need MDS 2.14.55 or later"
24076         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24077
24078         local testdir="$DIR/$tdir/striped_dir"
24079         local dir1=$testdir/dir1
24080         local dir2=$testdir/dir2
24081
24082         mkdir -p $testdir
24083
24084         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24085                 error "failed to set default stripe count for $testdir"
24086
24087         mkdir $dir1
24088         local stripe_count=$($LFS getdirstripe -c $dir1)
24089
24090         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24091
24092         local max_count=$((MDSCOUNT - 1))
24093         local mdts=$(comma_list $(mdts_nodes))
24094
24095         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24096         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24097
24098         mkdir $dir2
24099         stripe_count=$($LFS getdirstripe -c $dir2)
24100
24101         (( $stripe_count == $max_count )) || error "wrong stripe count"
24102 }
24103 run_test 300t "test max_mdt_stripecount"
24104
24105 prepare_remote_file() {
24106         mkdir $DIR/$tdir/src_dir ||
24107                 error "create remote source failed"
24108
24109         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24110                  error "cp to remote source failed"
24111         touch $DIR/$tdir/src_dir/a
24112
24113         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24114                 error "create remote target dir failed"
24115
24116         touch $DIR/$tdir/tgt_dir/b
24117
24118         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24119                 error "rename dir cross MDT failed!"
24120
24121         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24122                 error "src_child still exists after rename"
24123
24124         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24125                 error "missing file(a) after rename"
24126
24127         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24128                 error "diff after rename"
24129 }
24130
24131 test_310a() {
24132         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24134
24135         local remote_file=$DIR/$tdir/tgt_dir/b
24136
24137         mkdir -p $DIR/$tdir
24138
24139         prepare_remote_file || error "prepare remote file failed"
24140
24141         #open-unlink file
24142         $OPENUNLINK $remote_file $remote_file ||
24143                 error "openunlink $remote_file failed"
24144         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24145 }
24146 run_test 310a "open unlink remote file"
24147
24148 test_310b() {
24149         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24151
24152         local remote_file=$DIR/$tdir/tgt_dir/b
24153
24154         mkdir -p $DIR/$tdir
24155
24156         prepare_remote_file || error "prepare remote file failed"
24157
24158         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24159         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24160         $CHECKSTAT -t file $remote_file || error "check file failed"
24161 }
24162 run_test 310b "unlink remote file with multiple links while open"
24163
24164 test_310c() {
24165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24166         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24167
24168         local remote_file=$DIR/$tdir/tgt_dir/b
24169
24170         mkdir -p $DIR/$tdir
24171
24172         prepare_remote_file || error "prepare remote file failed"
24173
24174         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24175         multiop_bg_pause $remote_file O_uc ||
24176                         error "mulitop failed for remote file"
24177         MULTIPID=$!
24178         $MULTIOP $DIR/$tfile Ouc
24179         kill -USR1 $MULTIPID
24180         wait $MULTIPID
24181 }
24182 run_test 310c "open-unlink remote file with multiple links"
24183
24184 #LU-4825
24185 test_311() {
24186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24187         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24188         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24189                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24190         remote_mds_nodsh && skip "remote MDS with nodsh"
24191
24192         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24193         local mdts=$(comma_list $(mdts_nodes))
24194
24195         mkdir -p $DIR/$tdir
24196         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24197         createmany -o $DIR/$tdir/$tfile. 1000
24198
24199         # statfs data is not real time, let's just calculate it
24200         old_iused=$((old_iused + 1000))
24201
24202         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24203                         osp.*OST0000*MDT0000.create_count")
24204         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24205                                 osp.*OST0000*MDT0000.max_create_count")
24206         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24207
24208         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24209         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24210         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24211
24212         unlinkmany $DIR/$tdir/$tfile. 1000
24213
24214         do_nodes $mdts "$LCTL set_param -n \
24215                         osp.*OST0000*.max_create_count=$max_count"
24216         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24217                 do_nodes $mdts "$LCTL set_param -n \
24218                                 osp.*OST0000*.create_count=$count"
24219         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24220                         grep "=0" && error "create_count is zero"
24221
24222         local new_iused
24223         for i in $(seq 120); do
24224                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24225                 # system may be too busy to destroy all objs in time, use
24226                 # a somewhat small value to not fail autotest
24227                 [ $((old_iused - new_iused)) -gt 400 ] && break
24228                 sleep 1
24229         done
24230
24231         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24232         [ $((old_iused - new_iused)) -gt 400 ] ||
24233                 error "objs not destroyed after unlink"
24234 }
24235 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24236
24237 zfs_oid_to_objid()
24238 {
24239         local ost=$1
24240         local objid=$2
24241
24242         local vdevdir=$(dirname $(facet_vdevice $ost))
24243         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24244         local zfs_zapid=$(do_facet $ost $cmd |
24245                           grep -w "/O/0/d$((objid%32))" -C 5 |
24246                           awk '/Object/{getline; print $1}')
24247         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24248                           awk "/$objid = /"'{printf $3}')
24249
24250         echo $zfs_objid
24251 }
24252
24253 zfs_object_blksz() {
24254         local ost=$1
24255         local objid=$2
24256
24257         local vdevdir=$(dirname $(facet_vdevice $ost))
24258         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24259         local blksz=$(do_facet $ost $cmd $objid |
24260                       awk '/dblk/{getline; printf $4}')
24261
24262         case "${blksz: -1}" in
24263                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24264                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24265                 *) ;;
24266         esac
24267
24268         echo $blksz
24269 }
24270
24271 test_312() { # LU-4856
24272         remote_ost_nodsh && skip "remote OST with nodsh"
24273         [ "$ost1_FSTYPE" = "zfs" ] ||
24274                 skip_env "the test only applies to zfs"
24275
24276         local max_blksz=$(do_facet ost1 \
24277                           $ZFS get -p recordsize $(facet_device ost1) |
24278                           awk '!/VALUE/{print $3}')
24279
24280         # to make life a little bit easier
24281         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24282         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24283
24284         local tf=$DIR/$tdir/$tfile
24285         touch $tf
24286         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24287
24288         # Get ZFS object id
24289         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24290         # block size change by sequential overwrite
24291         local bs
24292
24293         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24294                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24295
24296                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24297                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24298         done
24299         rm -f $tf
24300
24301         # block size change by sequential append write
24302         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24303         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24304         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24305         local count
24306
24307         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24308                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24309                         oflag=sync conv=notrunc
24310
24311                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24312                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24313                         error "blksz error, actual $blksz, " \
24314                                 "expected: 2 * $count * $PAGE_SIZE"
24315         done
24316         rm -f $tf
24317
24318         # random write
24319         touch $tf
24320         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24321         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24322
24323         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24324         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24325         [ $blksz -eq $PAGE_SIZE ] ||
24326                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24327
24328         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24329         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24330         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24331
24332         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24333         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24334         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24335 }
24336 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24337
24338 test_313() {
24339         remote_ost_nodsh && skip "remote OST with nodsh"
24340
24341         local file=$DIR/$tfile
24342
24343         rm -f $file
24344         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24345
24346         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24347         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24348         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24349                 error "write should failed"
24350         do_facet ost1 "$LCTL set_param fail_loc=0"
24351         rm -f $file
24352 }
24353 run_test 313 "io should fail after last_rcvd update fail"
24354
24355 test_314() {
24356         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24357
24358         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24359         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24360         rm -f $DIR/$tfile
24361         wait_delete_completed
24362         do_facet ost1 "$LCTL set_param fail_loc=0"
24363 }
24364 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24365
24366 test_315() { # LU-618
24367         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24368
24369         local file=$DIR/$tfile
24370         rm -f $file
24371
24372         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24373                 error "multiop file write failed"
24374         $MULTIOP $file oO_RDONLY:r4063232_c &
24375         PID=$!
24376
24377         sleep 2
24378
24379         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24380         kill -USR1 $PID
24381
24382         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24383         rm -f $file
24384 }
24385 run_test 315 "read should be accounted"
24386
24387 test_316() {
24388         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24389         large_xattr_enabled || skip "ea_inode feature disabled"
24390
24391         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24392         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24393         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24394         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24395
24396         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24397 }
24398 run_test 316 "lfs migrate of file with large_xattr enabled"
24399
24400 test_317() {
24401         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24402                 skip "Need MDS version at least 2.11.53"
24403         if [ "$ost1_FSTYPE" == "zfs" ]; then
24404                 skip "LU-10370: no implementation for ZFS"
24405         fi
24406
24407         local trunc_sz
24408         local grant_blk_size
24409
24410         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24411                         awk '/grant_block_size:/ { print $2; exit; }')
24412         #
24413         # Create File of size 5M. Truncate it to below size's and verify
24414         # blocks count.
24415         #
24416         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24417                 error "Create file $DIR/$tfile failed"
24418         stack_trap "rm -f $DIR/$tfile" EXIT
24419
24420         for trunc_sz in 2097152 4097 4000 509 0; do
24421                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24422                         error "truncate $tfile to $trunc_sz failed"
24423                 local sz=$(stat --format=%s $DIR/$tfile)
24424                 local blk=$(stat --format=%b $DIR/$tfile)
24425                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24426                                      grant_blk_size) * 8))
24427
24428                 if [[ $blk -ne $trunc_blk ]]; then
24429                         $(which stat) $DIR/$tfile
24430                         error "Expected Block $trunc_blk got $blk for $tfile"
24431                 fi
24432
24433                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24434                         error "Expected Size $trunc_sz got $sz for $tfile"
24435         done
24436
24437         #
24438         # sparse file test
24439         # Create file with a hole and write actual 65536 bytes which aligned
24440         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24441         #
24442         local bs=65536
24443         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24444                 error "Create file : $DIR/$tfile"
24445
24446         #
24447         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24448         # blocks. The block count must drop to 8.
24449         #
24450         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24451                 ((bs - grant_blk_size) + 1)))
24452         $TRUNCATE $DIR/$tfile $trunc_sz ||
24453                 error "truncate $tfile to $trunc_sz failed"
24454
24455         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24456         sz=$(stat --format=%s $DIR/$tfile)
24457         blk=$(stat --format=%b $DIR/$tfile)
24458
24459         if [[ $blk -ne $trunc_bsz ]]; then
24460                 $(which stat) $DIR/$tfile
24461                 error "Expected Block $trunc_bsz got $blk for $tfile"
24462         fi
24463
24464         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24465                 error "Expected Size $trunc_sz got $sz for $tfile"
24466 }
24467 run_test 317 "Verify blocks get correctly update after truncate"
24468
24469 test_318() {
24470         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24471         local old_max_active=$($LCTL get_param -n \
24472                             ${llite_name}.max_read_ahead_async_active \
24473                             2>/dev/null)
24474
24475         $LCTL set_param llite.*.max_read_ahead_async_active=256
24476         local max_active=$($LCTL get_param -n \
24477                            ${llite_name}.max_read_ahead_async_active \
24478                            2>/dev/null)
24479         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24480
24481         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24482                 error "set max_read_ahead_async_active should succeed"
24483
24484         $LCTL set_param llite.*.max_read_ahead_async_active=512
24485         max_active=$($LCTL get_param -n \
24486                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24487         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24488
24489         # restore @max_active
24490         [ $old_max_active -ne 0 ] && $LCTL set_param \
24491                 llite.*.max_read_ahead_async_active=$old_max_active
24492
24493         local old_threshold=$($LCTL get_param -n \
24494                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24495         local max_per_file_mb=$($LCTL get_param -n \
24496                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24497
24498         local invalid=$(($max_per_file_mb + 1))
24499         $LCTL set_param \
24500                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24501                         && error "set $invalid should fail"
24502
24503         local valid=$(($invalid - 1))
24504         $LCTL set_param \
24505                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24506                         error "set $valid should succeed"
24507         local threshold=$($LCTL get_param -n \
24508                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24509         [ $threshold -eq $valid ] || error \
24510                 "expect threshold $valid got $threshold"
24511         $LCTL set_param \
24512                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24513 }
24514 run_test 318 "Verify async readahead tunables"
24515
24516 test_319() {
24517         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24518
24519         local before=$(date +%s)
24520         local evict
24521         local mdir=$DIR/$tdir
24522         local file=$mdir/xxx
24523
24524         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24525         touch $file
24526
24527 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24528         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24529         $LFS migrate -m1 $mdir &
24530
24531         sleep 1
24532         dd if=$file of=/dev/null
24533         wait
24534         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24535           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24536
24537         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24538 }
24539 run_test 319 "lost lease lock on migrate error"
24540
24541 test_398a() { # LU-4198
24542         local ost1_imp=$(get_osc_import_name client ost1)
24543         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24544                          cut -d'.' -f2)
24545
24546         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24547         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24548
24549         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24550         # request a new lock on client
24551         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24552
24553         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24554         #local lock_count=$($LCTL get_param -n \
24555         #                  ldlm.namespaces.$imp_name.lru_size)
24556         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24557
24558         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24559
24560         # no lock cached, should use lockless DIO and not enqueue new lock
24561         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24562                 conv=notrunc ||
24563                 error "dio write failed"
24564         lock_count=$($LCTL get_param -n \
24565                      ldlm.namespaces.$imp_name.lru_size)
24566         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24567
24568         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24569
24570         # no lock cached, should use locked DIO append
24571         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24572                 conv=notrunc || error "DIO append failed"
24573         lock_count=$($LCTL get_param -n \
24574                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24575         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24576 }
24577 run_test 398a "direct IO should cancel lock otherwise lockless"
24578
24579 test_398b() { # LU-4198
24580         which fio || skip_env "no fio installed"
24581         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24582
24583         local size=48
24584         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24585
24586         local njobs=4
24587         # Single page, multiple pages, stripe size, 4*stripe size
24588         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24589                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24590                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24591                         --numjobs=$njobs --fallocate=none \
24592                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24593                         --filename=$DIR/$tfile &
24594                 bg_pid=$!
24595
24596                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24597                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24598                         --numjobs=$njobs --fallocate=none \
24599                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24600                         --filename=$DIR/$tfile || true
24601                 wait $bg_pid
24602         done
24603
24604         evict=$(do_facet client $LCTL get_param \
24605                 osc.$FSNAME-OST*-osc-*/state |
24606             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24607
24608         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24609                 (do_facet client $LCTL get_param \
24610                         osc.$FSNAME-OST*-osc-*/state;
24611                     error "eviction happened: $evict before:$before")
24612
24613         rm -f $DIR/$tfile
24614 }
24615 run_test 398b "DIO and buffer IO race"
24616
24617 test_398c() { # LU-4198
24618         local ost1_imp=$(get_osc_import_name client ost1)
24619         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24620                          cut -d'.' -f2)
24621
24622         which fio || skip_env "no fio installed"
24623
24624         saved_debug=$($LCTL get_param -n debug)
24625         $LCTL set_param debug=0
24626
24627         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24628         ((size /= 1024)) # by megabytes
24629         ((size /= 2)) # write half of the OST at most
24630         [ $size -gt 40 ] && size=40 #reduce test time anyway
24631
24632         $LFS setstripe -c 1 $DIR/$tfile
24633
24634         # it seems like ldiskfs reserves more space than necessary if the
24635         # writing blocks are not mapped, so it extends the file firstly
24636         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24637         cancel_lru_locks osc
24638
24639         # clear and verify rpc_stats later
24640         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24641
24642         local njobs=4
24643         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24644         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24645                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24646                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24647                 --filename=$DIR/$tfile
24648         [ $? -eq 0 ] || error "fio write error"
24649
24650         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24651                 error "Locks were requested while doing AIO"
24652
24653         # get the percentage of 1-page I/O
24654         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24655                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24656                 awk '{print $7}')
24657         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24658
24659         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24660         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24661                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24662                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24663                 --filename=$DIR/$tfile
24664         [ $? -eq 0 ] || error "fio mixed read write error"
24665
24666         echo "AIO with large block size ${size}M"
24667         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24668                 --numjobs=1 --fallocate=none --ioengine=libaio \
24669                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24670                 --filename=$DIR/$tfile
24671         [ $? -eq 0 ] || error "fio large block size failed"
24672
24673         rm -f $DIR/$tfile
24674         $LCTL set_param debug="$saved_debug"
24675 }
24676 run_test 398c "run fio to test AIO"
24677
24678 test_398d() { #  LU-13846
24679         which aiocp || skip_env "no aiocp installed"
24680         local aio_file=$DIR/$tfile.aio
24681
24682         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24683
24684         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24685         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24686         stack_trap "rm -f $DIR/$tfile $aio_file"
24687
24688         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24689
24690         # make sure we don't crash and fail properly
24691         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24692                 error "aio not aligned with PAGE SIZE should fail"
24693
24694         rm -f $DIR/$tfile $aio_file
24695 }
24696 run_test 398d "run aiocp to verify block size > stripe size"
24697
24698 test_398e() {
24699         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24700         touch $DIR/$tfile.new
24701         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24702 }
24703 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24704
24705 test_398f() { #  LU-14687
24706         which aiocp || skip_env "no aiocp installed"
24707         local aio_file=$DIR/$tfile.aio
24708
24709         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24710
24711         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24712         stack_trap "rm -f $DIR/$tfile $aio_file"
24713
24714         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24715         $LCTL set_param fail_loc=0x1418
24716         # make sure we don't crash and fail properly
24717         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24718                 error "aio with page allocation failure succeeded"
24719         $LCTL set_param fail_loc=0
24720         diff $DIR/$tfile $aio_file
24721         [[ $? != 0 ]] || error "no diff after failed aiocp"
24722 }
24723 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24724
24725 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24726 # stripe and i/o size must be > stripe size
24727 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24728 # single RPC in flight.  This test shows async DIO submission is working by
24729 # showing multiple RPCs in flight.
24730 test_398g() { #  LU-13798
24731         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24732
24733         # We need to do some i/o first to acquire enough grant to put our RPCs
24734         # in flight; otherwise a new connection may not have enough grant
24735         # available
24736         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24737                 error "parallel dio failed"
24738         stack_trap "rm -f $DIR/$tfile"
24739
24740         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24741         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24742         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24743         stack_trap "$LCTL set_param -n $pages_per_rpc"
24744
24745         # Recreate file so it's empty
24746         rm -f $DIR/$tfile
24747         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24748         #Pause rpc completion to guarantee we see multiple rpcs in flight
24749         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24750         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24751         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24752
24753         # Clear rpc stats
24754         $LCTL set_param osc.*.rpc_stats=c
24755
24756         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24757                 error "parallel dio failed"
24758         stack_trap "rm -f $DIR/$tfile"
24759
24760         $LCTL get_param osc.*-OST0000-*.rpc_stats
24761         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24762                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24763                 grep "8:" | awk '{print $8}')
24764         # We look at the "8 rpcs in flight" field, and verify A) it is present
24765         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24766         # as expected for an 8M DIO to a file with 1M stripes.
24767         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24768
24769         # Verify turning off parallel dio works as expected
24770         # Clear rpc stats
24771         $LCTL set_param osc.*.rpc_stats=c
24772         $LCTL set_param llite.*.parallel_dio=0
24773         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24774
24775         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24776                 error "dio with parallel dio disabled failed"
24777
24778         # Ideally, we would see only one RPC in flight here, but there is an
24779         # unavoidable race between i/o completion and RPC in flight counting,
24780         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24781         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24782         # So instead we just verify it's always < 8.
24783         $LCTL get_param osc.*-OST0000-*.rpc_stats
24784         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24785                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24786                 grep '^$' -B1 | grep . | awk '{print $1}')
24787         [ $ret != "8:" ] ||
24788                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24789 }
24790 run_test 398g "verify parallel dio async RPC submission"
24791
24792 test_398h() { #  LU-13798
24793         local dio_file=$DIR/$tfile.dio
24794
24795         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24796
24797         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24798         stack_trap "rm -f $DIR/$tfile $dio_file"
24799
24800         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24801                 error "parallel dio failed"
24802         diff $DIR/$tfile $dio_file
24803         [[ $? == 0 ]] || error "file diff after aiocp"
24804 }
24805 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24806
24807 test_398i() { #  LU-13798
24808         local dio_file=$DIR/$tfile.dio
24809
24810         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24811
24812         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24813         stack_trap "rm -f $DIR/$tfile $dio_file"
24814
24815         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24816         $LCTL set_param fail_loc=0x1418
24817         # make sure we don't crash and fail properly
24818         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24819                 error "parallel dio page allocation failure succeeded"
24820         diff $DIR/$tfile $dio_file
24821         [[ $? != 0 ]] || error "no diff after failed aiocp"
24822 }
24823 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24824
24825 test_398j() { #  LU-13798
24826         # Stripe size > RPC size but less than i/o size tests split across
24827         # stripes and RPCs for individual i/o op
24828         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24829
24830         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24831         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24832         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24833         stack_trap "$LCTL set_param -n $pages_per_rpc"
24834
24835         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24836                 error "parallel dio write failed"
24837         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24838
24839         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24840                 error "parallel dio read failed"
24841         diff $DIR/$tfile $DIR/$tfile.2
24842         [[ $? == 0 ]] || error "file diff after parallel dio read"
24843 }
24844 run_test 398j "test parallel dio where stripe size > rpc_size"
24845
24846 test_398k() { #  LU-13798
24847         wait_delete_completed
24848         wait_mds_ost_sync
24849
24850         # 4 stripe file; we will cause out of space on OST0
24851         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24852
24853         # Fill OST0 (if it's not too large)
24854         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24855                    head -n1)
24856         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24857                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24858         fi
24859         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24860         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24861                 error "dd should fill OST0"
24862         stack_trap "rm -f $DIR/$tfile.1"
24863
24864         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24865         err=$?
24866
24867         ls -la $DIR/$tfile
24868         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24869                 error "file is not 0 bytes in size"
24870
24871         # dd above should not succeed, but don't error until here so we can
24872         # get debug info above
24873         [[ $err != 0 ]] ||
24874                 error "parallel dio write with enospc succeeded"
24875         stack_trap "rm -f $DIR/$tfile"
24876 }
24877 run_test 398k "test enospc on first stripe"
24878
24879 test_398l() { #  LU-13798
24880         wait_delete_completed
24881         wait_mds_ost_sync
24882
24883         # 4 stripe file; we will cause out of space on OST0
24884         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24885         # happens on the second i/o chunk we issue
24886         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24887
24888         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24889         stack_trap "rm -f $DIR/$tfile"
24890
24891         # Fill OST0 (if it's not too large)
24892         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24893                    head -n1)
24894         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24895                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24896         fi
24897         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24898         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24899                 error "dd should fill OST0"
24900         stack_trap "rm -f $DIR/$tfile.1"
24901
24902         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24903         err=$?
24904         stack_trap "rm -f $DIR/$tfile.2"
24905
24906         # Check that short write completed as expected
24907         ls -la $DIR/$tfile.2
24908         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24909                 error "file is not 1M in size"
24910
24911         # dd above should not succeed, but don't error until here so we can
24912         # get debug info above
24913         [[ $err != 0 ]] ||
24914                 error "parallel dio write with enospc succeeded"
24915
24916         # Truncate source file to same length as output file and diff them
24917         $TRUNCATE $DIR/$tfile 1048576
24918         diff $DIR/$tfile $DIR/$tfile.2
24919         [[ $? == 0 ]] || error "data incorrect after short write"
24920 }
24921 run_test 398l "test enospc on intermediate stripe/RPC"
24922
24923 test_398m() { #  LU-13798
24924         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24925
24926         # Set up failure on OST0, the first stripe:
24927         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24928         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24929         # So this fail_val specifies OST0
24930         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24931         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24932
24933         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24934                 error "parallel dio write with failure on first stripe succeeded"
24935         stack_trap "rm -f $DIR/$tfile"
24936         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24937
24938         # Place data in file for read
24939         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24940                 error "parallel dio write failed"
24941
24942         # Fail read on OST0, first stripe
24943         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24944         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24945         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24946                 error "parallel dio read with error on first stripe succeeded"
24947         rm -f $DIR/$tfile.2
24948         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24949
24950         # Switch to testing on OST1, second stripe
24951         # Clear file contents, maintain striping
24952         echo > $DIR/$tfile
24953         # Set up failure on OST1, second stripe:
24954         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24955         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24956
24957         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24958                 error "parallel dio write with failure on first stripe succeeded"
24959         stack_trap "rm -f $DIR/$tfile"
24960         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24961
24962         # Place data in file for read
24963         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24964                 error "parallel dio write failed"
24965
24966         # Fail read on OST1, second stripe
24967         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24968         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24969         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24970                 error "parallel dio read with error on first stripe succeeded"
24971         rm -f $DIR/$tfile.2
24972         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24973 }
24974 run_test 398m "test RPC failures with parallel dio"
24975
24976 # Parallel submission of DIO should not cause problems for append, but it's
24977 # important to verify.
24978 test_398n() { #  LU-13798
24979         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24980
24981         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24982                 error "dd to create source file failed"
24983         stack_trap "rm -f $DIR/$tfile"
24984
24985         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24986                 error "parallel dio write with failure on second stripe succeeded"
24987         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24988         diff $DIR/$tfile $DIR/$tfile.1
24989         [[ $? == 0 ]] || error "data incorrect after append"
24990
24991 }
24992 run_test 398n "test append with parallel DIO"
24993
24994 test_fake_rw() {
24995         local read_write=$1
24996         if [ "$read_write" = "write" ]; then
24997                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24998         elif [ "$read_write" = "read" ]; then
24999                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25000         else
25001                 error "argument error"
25002         fi
25003
25004         # turn off debug for performance testing
25005         local saved_debug=$($LCTL get_param -n debug)
25006         $LCTL set_param debug=0
25007
25008         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25009
25010         # get ost1 size - $FSNAME-OST0000
25011         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25012         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25013         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25014
25015         if [ "$read_write" = "read" ]; then
25016                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25017         fi
25018
25019         local start_time=$(date +%s.%N)
25020         $dd_cmd bs=1M count=$blocks oflag=sync ||
25021                 error "real dd $read_write error"
25022         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25023
25024         if [ "$read_write" = "write" ]; then
25025                 rm -f $DIR/$tfile
25026         fi
25027
25028         # define OBD_FAIL_OST_FAKE_RW           0x238
25029         do_facet ost1 $LCTL set_param fail_loc=0x238
25030
25031         local start_time=$(date +%s.%N)
25032         $dd_cmd bs=1M count=$blocks oflag=sync ||
25033                 error "fake dd $read_write error"
25034         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25035
25036         if [ "$read_write" = "write" ]; then
25037                 # verify file size
25038                 cancel_lru_locks osc
25039                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25040                         error "$tfile size not $blocks MB"
25041         fi
25042         do_facet ost1 $LCTL set_param fail_loc=0
25043
25044         echo "fake $read_write $duration_fake vs. normal $read_write" \
25045                 "$duration in seconds"
25046         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25047                 error_not_in_vm "fake write is slower"
25048
25049         $LCTL set_param -n debug="$saved_debug"
25050         rm -f $DIR/$tfile
25051 }
25052 test_399a() { # LU-7655 for OST fake write
25053         remote_ost_nodsh && skip "remote OST with nodsh"
25054
25055         test_fake_rw write
25056 }
25057 run_test 399a "fake write should not be slower than normal write"
25058
25059 test_399b() { # LU-8726 for OST fake read
25060         remote_ost_nodsh && skip "remote OST with nodsh"
25061         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25062                 skip_env "ldiskfs only test"
25063         fi
25064
25065         test_fake_rw read
25066 }
25067 run_test 399b "fake read should not be slower than normal read"
25068
25069 test_400a() { # LU-1606, was conf-sanity test_74
25070         if ! which $CC > /dev/null 2>&1; then
25071                 skip_env "$CC is not installed"
25072         fi
25073
25074         local extra_flags=''
25075         local out=$TMP/$tfile
25076         local prefix=/usr/include/lustre
25077         local prog
25078
25079         # Oleg removes c files in his test rig so test if any c files exist
25080         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25081                 skip_env "Needed c test files are missing"
25082
25083         if ! [[ -d $prefix ]]; then
25084                 # Assume we're running in tree and fixup the include path.
25085                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25086                 extra_flags+=" -L$LUSTRE/utils/.lib"
25087         fi
25088
25089         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25090                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25091                         error "client api broken"
25092         done
25093         rm -f $out
25094 }
25095 run_test 400a "Lustre client api program can compile and link"
25096
25097 test_400b() { # LU-1606, LU-5011
25098         local header
25099         local out=$TMP/$tfile
25100         local prefix=/usr/include/linux/lustre
25101
25102         # We use a hard coded prefix so that this test will not fail
25103         # when run in tree. There are headers in lustre/include/lustre/
25104         # that are not packaged (like lustre_idl.h) and have more
25105         # complicated include dependencies (like config.h and lnet/types.h).
25106         # Since this test about correct packaging we just skip them when
25107         # they don't exist (see below) rather than try to fixup cppflags.
25108
25109         if ! which $CC > /dev/null 2>&1; then
25110                 skip_env "$CC is not installed"
25111         fi
25112
25113         for header in $prefix/*.h; do
25114                 if ! [[ -f "$header" ]]; then
25115                         continue
25116                 fi
25117
25118                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25119                         continue # lustre_ioctl.h is internal header
25120                 fi
25121
25122                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25123                         error "cannot compile '$header'"
25124         done
25125         rm -f $out
25126 }
25127 run_test 400b "packaged headers can be compiled"
25128
25129 test_401a() { #LU-7437
25130         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25131         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25132
25133         #count the number of parameters by "list_param -R"
25134         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25135         #count the number of parameters by listing proc files
25136         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25137         echo "proc_dirs='$proc_dirs'"
25138         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25139         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25140                       sort -u | wc -l)
25141
25142         [ $params -eq $procs ] ||
25143                 error "found $params parameters vs. $procs proc files"
25144
25145         # test the list_param -D option only returns directories
25146         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25147         #count the number of parameters by listing proc directories
25148         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25149                 sort -u | wc -l)
25150
25151         [ $params -eq $procs ] ||
25152                 error "found $params parameters vs. $procs proc files"
25153 }
25154 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25155
25156 test_401b() {
25157         # jobid_var may not allow arbitrary values, so use jobid_name
25158         # if available
25159         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25160                 local testname=jobid_name tmp='testing%p'
25161         else
25162                 local testname=jobid_var tmp=testing
25163         fi
25164
25165         local save=$($LCTL get_param -n $testname)
25166
25167         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25168                 error "no error returned when setting bad parameters"
25169
25170         local jobid_new=$($LCTL get_param -n foe $testname baz)
25171         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25172
25173         $LCTL set_param -n fog=bam $testname=$save bat=fog
25174         local jobid_old=$($LCTL get_param -n foe $testname bag)
25175         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25176 }
25177 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25178
25179 test_401c() {
25180         # jobid_var may not allow arbitrary values, so use jobid_name
25181         # if available
25182         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25183                 local testname=jobid_name
25184         else
25185                 local testname=jobid_var
25186         fi
25187
25188         local jobid_var_old=$($LCTL get_param -n $testname)
25189         local jobid_var_new
25190
25191         $LCTL set_param $testname= &&
25192                 error "no error returned for 'set_param a='"
25193
25194         jobid_var_new=$($LCTL get_param -n $testname)
25195         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25196                 error "$testname was changed by setting without value"
25197
25198         $LCTL set_param $testname &&
25199                 error "no error returned for 'set_param a'"
25200
25201         jobid_var_new=$($LCTL get_param -n $testname)
25202         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25203                 error "$testname was changed by setting without value"
25204 }
25205 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25206
25207 test_401d() {
25208         # jobid_var may not allow arbitrary values, so use jobid_name
25209         # if available
25210         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25211                 local testname=jobid_name new_value='foo=bar%p'
25212         else
25213                 local testname=jobid_var new_valuie=foo=bar
25214         fi
25215
25216         local jobid_var_old=$($LCTL get_param -n $testname)
25217         local jobid_var_new
25218
25219         $LCTL set_param $testname=$new_value ||
25220                 error "'set_param a=b' did not accept a value containing '='"
25221
25222         jobid_var_new=$($LCTL get_param -n $testname)
25223         [[ "$jobid_var_new" == "$new_value" ]] ||
25224                 error "'set_param a=b' failed on a value containing '='"
25225
25226         # Reset the $testname to test the other format
25227         $LCTL set_param $testname=$jobid_var_old
25228         jobid_var_new=$($LCTL get_param -n $testname)
25229         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25230                 error "failed to reset $testname"
25231
25232         $LCTL set_param $testname $new_value ||
25233                 error "'set_param a b' did not accept a value containing '='"
25234
25235         jobid_var_new=$($LCTL get_param -n $testname)
25236         [[ "$jobid_var_new" == "$new_value" ]] ||
25237                 error "'set_param a b' failed on a value containing '='"
25238
25239         $LCTL set_param $testname $jobid_var_old
25240         jobid_var_new=$($LCTL get_param -n $testname)
25241         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25242                 error "failed to reset $testname"
25243 }
25244 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25245
25246 test_401e() { # LU-14779
25247         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25248                 error "lctl list_param MGC* failed"
25249         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25250         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25251                 error "lctl get_param lru_size failed"
25252 }
25253 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25254
25255 test_402() {
25256         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25257         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25258                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25259         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25260                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25261                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25262         remote_mds_nodsh && skip "remote MDS with nodsh"
25263
25264         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25265 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25266         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25267         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25268                 echo "Touch failed - OK"
25269 }
25270 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25271
25272 test_403() {
25273         local file1=$DIR/$tfile.1
25274         local file2=$DIR/$tfile.2
25275         local tfile=$TMP/$tfile
25276
25277         rm -f $file1 $file2 $tfile
25278
25279         touch $file1
25280         ln $file1 $file2
25281
25282         # 30 sec OBD_TIMEOUT in ll_getattr()
25283         # right before populating st_nlink
25284         $LCTL set_param fail_loc=0x80001409
25285         stat -c %h $file1 > $tfile &
25286
25287         # create an alias, drop all locks and reclaim the dentry
25288         < $file2
25289         cancel_lru_locks mdc
25290         cancel_lru_locks osc
25291         sysctl -w vm.drop_caches=2
25292
25293         wait
25294
25295         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25296
25297         rm -f $tfile $file1 $file2
25298 }
25299 run_test 403 "i_nlink should not drop to zero due to aliasing"
25300
25301 test_404() { # LU-6601
25302         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25303                 skip "Need server version newer than 2.8.52"
25304         remote_mds_nodsh && skip "remote MDS with nodsh"
25305
25306         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25307                 awk '/osp .*-osc-MDT/ { print $4}')
25308
25309         local osp
25310         for osp in $mosps; do
25311                 echo "Deactivate: " $osp
25312                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25313                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25314                         awk -vp=$osp '$4 == p { print $2 }')
25315                 [ $stat = IN ] || {
25316                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25317                         error "deactivate error"
25318                 }
25319                 echo "Activate: " $osp
25320                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25321                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25322                         awk -vp=$osp '$4 == p { print $2 }')
25323                 [ $stat = UP ] || {
25324                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25325                         error "activate error"
25326                 }
25327         done
25328 }
25329 run_test 404 "validate manual {de}activated works properly for OSPs"
25330
25331 test_405() {
25332         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25333         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25334                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25335                         skip "Layout swap lock is not supported"
25336
25337         check_swap_layouts_support
25338         check_swap_layout_no_dom $DIR
25339
25340         test_mkdir $DIR/$tdir
25341         swap_lock_test -d $DIR/$tdir ||
25342                 error "One layout swap locked test failed"
25343 }
25344 run_test 405 "Various layout swap lock tests"
25345
25346 test_406() {
25347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25348         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25349         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25351         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25352                 skip "Need MDS version at least 2.8.50"
25353
25354         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25355         local test_pool=$TESTNAME
25356
25357         pool_add $test_pool || error "pool_add failed"
25358         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25359                 error "pool_add_targets failed"
25360
25361         save_layout_restore_at_exit $MOUNT
25362
25363         # parent set default stripe count only, child will stripe from both
25364         # parent and fs default
25365         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25366                 error "setstripe $MOUNT failed"
25367         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25368         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25369         for i in $(seq 10); do
25370                 local f=$DIR/$tdir/$tfile.$i
25371                 touch $f || error "touch failed"
25372                 local count=$($LFS getstripe -c $f)
25373                 [ $count -eq $OSTCOUNT ] ||
25374                         error "$f stripe count $count != $OSTCOUNT"
25375                 local offset=$($LFS getstripe -i $f)
25376                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25377                 local size=$($LFS getstripe -S $f)
25378                 [ $size -eq $((def_stripe_size * 2)) ] ||
25379                         error "$f stripe size $size != $((def_stripe_size * 2))"
25380                 local pool=$($LFS getstripe -p $f)
25381                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25382         done
25383
25384         # change fs default striping, delete parent default striping, now child
25385         # will stripe from new fs default striping only
25386         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25387                 error "change $MOUNT default stripe failed"
25388         $LFS setstripe -c 0 $DIR/$tdir ||
25389                 error "delete $tdir default stripe failed"
25390         for i in $(seq 11 20); do
25391                 local f=$DIR/$tdir/$tfile.$i
25392                 touch $f || error "touch $f failed"
25393                 local count=$($LFS getstripe -c $f)
25394                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25395                 local offset=$($LFS getstripe -i $f)
25396                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25397                 local size=$($LFS getstripe -S $f)
25398                 [ $size -eq $def_stripe_size ] ||
25399                         error "$f stripe size $size != $def_stripe_size"
25400                 local pool=$($LFS getstripe -p $f)
25401                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25402         done
25403
25404         unlinkmany $DIR/$tdir/$tfile. 1 20
25405
25406         local f=$DIR/$tdir/$tfile
25407         pool_remove_all_targets $test_pool $f
25408         pool_remove $test_pool $f
25409 }
25410 run_test 406 "DNE support fs default striping"
25411
25412 test_407() {
25413         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25414         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25415                 skip "Need MDS version at least 2.8.55"
25416         remote_mds_nodsh && skip "remote MDS with nodsh"
25417
25418         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25419                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25420         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25421                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25422         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25423
25424         #define OBD_FAIL_DT_TXN_STOP    0x2019
25425         for idx in $(seq $MDSCOUNT); do
25426                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25427         done
25428         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25429         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25430                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25431         true
25432 }
25433 run_test 407 "transaction fail should cause operation fail"
25434
25435 test_408() {
25436         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25437
25438         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25439         lctl set_param fail_loc=0x8000040a
25440         # let ll_prepare_partial_page() fail
25441         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25442
25443         rm -f $DIR/$tfile
25444
25445         # create at least 100 unused inodes so that
25446         # shrink_icache_memory(0) should not return 0
25447         touch $DIR/$tfile-{0..100}
25448         rm -f $DIR/$tfile-{0..100}
25449         sync
25450
25451         echo 2 > /proc/sys/vm/drop_caches
25452 }
25453 run_test 408 "drop_caches should not hang due to page leaks"
25454
25455 test_409()
25456 {
25457         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25458
25459         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25460         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25461         touch $DIR/$tdir/guard || error "(2) Fail to create"
25462
25463         local PREFIX=$(str_repeat 'A' 128)
25464         echo "Create 1K hard links start at $(date)"
25465         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25466                 error "(3) Fail to hard link"
25467
25468         echo "Links count should be right although linkEA overflow"
25469         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25470         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25471         [ $linkcount -eq 1001 ] ||
25472                 error "(5) Unexpected hard links count: $linkcount"
25473
25474         echo "List all links start at $(date)"
25475         ls -l $DIR/$tdir/foo > /dev/null ||
25476                 error "(6) Fail to list $DIR/$tdir/foo"
25477
25478         echo "Unlink hard links start at $(date)"
25479         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25480                 error "(7) Fail to unlink"
25481         echo "Unlink hard links finished at $(date)"
25482 }
25483 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25484
25485 test_410()
25486 {
25487         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25488                 skip "Need client version at least 2.9.59"
25489         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25490                 skip "Need MODULES build"
25491
25492         # Create a file, and stat it from the kernel
25493         local testfile=$DIR/$tfile
25494         touch $testfile
25495
25496         local run_id=$RANDOM
25497         local my_ino=$(stat --format "%i" $testfile)
25498
25499         # Try to insert the module. This will always fail as the
25500         # module is designed to not be inserted.
25501         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25502             &> /dev/null
25503
25504         # Anything but success is a test failure
25505         dmesg | grep -q \
25506             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25507             error "no inode match"
25508 }
25509 run_test 410 "Test inode number returned from kernel thread"
25510
25511 cleanup_test411_cgroup() {
25512         trap 0
25513         rmdir "$1"
25514 }
25515
25516 test_411() {
25517         local cg_basedir=/sys/fs/cgroup/memory
25518         # LU-9966
25519         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25520                 skip "no setup for cgroup"
25521
25522         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25523                 error "test file creation failed"
25524         cancel_lru_locks osc
25525
25526         # Create a very small memory cgroup to force a slab allocation error
25527         local cgdir=$cg_basedir/osc_slab_alloc
25528         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25529         trap "cleanup_test411_cgroup $cgdir" EXIT
25530         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25531         echo 1M > $cgdir/memory.limit_in_bytes
25532
25533         # Should not LBUG, just be killed by oom-killer
25534         # dd will return 0 even allocation failure in some environment.
25535         # So don't check return value
25536         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25537         cleanup_test411_cgroup $cgdir
25538
25539         return 0
25540 }
25541 run_test 411 "Slab allocation error with cgroup does not LBUG"
25542
25543 test_412() {
25544         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25545         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25546                 skip "Need server version at least 2.10.55"
25547
25548         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25549                 error "mkdir failed"
25550         $LFS getdirstripe $DIR/$tdir
25551         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25552         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25553                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25554         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25555         [ $stripe_count -eq 2 ] ||
25556                 error "expect 2 get $stripe_count"
25557
25558         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25559
25560         local index
25561         local index2
25562
25563         # subdirs should be on the same MDT as parent
25564         for i in $(seq 0 $((MDSCOUNT - 1))); do
25565                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25566                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25567                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25568                 (( index == i )) || error "mdt$i/sub on MDT$index"
25569         done
25570
25571         # stripe offset -1, ditto
25572         for i in {1..10}; do
25573                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25574                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25575                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25576                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25577                 (( index == index2 )) ||
25578                         error "qos$i on MDT$index, sub on MDT$index2"
25579         done
25580
25581         local testdir=$DIR/$tdir/inherit
25582
25583         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25584         # inherit 2 levels
25585         for i in 1 2; do
25586                 testdir=$testdir/s$i
25587                 mkdir $testdir || error "mkdir $testdir failed"
25588                 index=$($LFS getstripe -m $testdir)
25589                 (( index == 1 )) ||
25590                         error "$testdir on MDT$index"
25591         done
25592
25593         # not inherit any more
25594         testdir=$testdir/s3
25595         mkdir $testdir || error "mkdir $testdir failed"
25596         getfattr -d -m dmv $testdir | grep dmv &&
25597                 error "default LMV set on $testdir" || true
25598 }
25599 run_test 412 "mkdir on specific MDTs"
25600
25601 TEST413_COUNT=${TEST413_COUNT:-200}
25602 generate_uneven_mdts() {
25603         local threshold=$1
25604         local lmv_qos_maxage
25605         local lod_qos_maxage
25606         local ffree
25607         local bavail
25608         local max
25609         local min
25610         local max_index
25611         local min_index
25612         local tmp
25613         local i
25614
25615         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25616         $LCTL set_param lmv.*.qos_maxage=1
25617         stack_trap "$LCTL set_param \
25618                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25619         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25620                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25621         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25622                 lod.*.mdt_qos_maxage=1
25623         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25624                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25625
25626         echo
25627         echo "Check for uneven MDTs: "
25628
25629         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25630         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25631         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25632
25633         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25634         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25635         max_index=0
25636         min_index=0
25637         for ((i = 1; i < ${#ffree[@]}; i++)); do
25638                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25639                 if [ $tmp -gt $max ]; then
25640                         max=$tmp
25641                         max_index=$i
25642                 fi
25643                 if [ $tmp -lt $min ]; then
25644                         min=$tmp
25645                         min_index=$i
25646                 fi
25647         done
25648
25649         (( ${ffree[min_index]} > 0 )) ||
25650                 skip "no free files in MDT$min_index"
25651         (( ${ffree[min_index]} < 10000000 )) ||
25652                 skip "too many free files in MDT$min_index"
25653
25654         # Check if we need to generate uneven MDTs
25655         local diff=$(((max - min) * 100 / min))
25656         local testdir=$DIR/$tdir-fillmdt
25657         local start
25658
25659         i=0
25660         while (( diff < threshold )); do
25661                 mkdir -p $testdir
25662                 # generate uneven MDTs, create till $threshold% diff
25663                 echo -n "weight diff=$diff% must be > $threshold% ..."
25664                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
25665                 testdir=$DIR/$tdir-fillmdt/$i
25666                 [ -d $testdir ] && continue
25667                 $LFS mkdir -i $min_index $testdir ||
25668                         error "mkdir $testdir failed"
25669                 $LFS setstripe -E 1M -L mdt $testdir ||
25670                         error "setstripe $testdir failed"
25671                 start=$SECONDS
25672                 for ((F=0; F < TEST413_COUNT; F++)); do
25673                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
25674                                 /dev/null 2>&1 || error "dd $F failed"
25675                 done
25676                 sync; sleep 1; sync
25677
25678                 # wait for QOS to update
25679                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25680
25681                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25682                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25683                 max=$(((${ffree[max_index]} >> 8) *
25684                         (${bavail[max_index]} * bsize >> 16)))
25685                 min=$(((${ffree[min_index]} >> 8) *
25686                         (${bavail[min_index]} * bsize >> 16)))
25687                 diff=$(((max - min) * 100 / min))
25688                 i=$((i + 1))
25689         done
25690
25691         echo "MDT filesfree available: ${ffree[*]}"
25692         echo "MDT blocks available: ${bavail[*]}"
25693         echo "weight diff=$diff%"
25694 }
25695
25696 test_qos_mkdir() {
25697         local mkdir_cmd=$1
25698         local stripe_count=$2
25699         local mdts=$(comma_list $(mdts_nodes))
25700
25701         local testdir
25702         local lmv_qos_prio_free
25703         local lmv_qos_threshold_rr
25704         local lmv_qos_maxage
25705         local lod_qos_prio_free
25706         local lod_qos_threshold_rr
25707         local lod_qos_maxage
25708         local count
25709         local i
25710
25711         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25712         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25713         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25714                 head -n1)
25715         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25716         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25717         stack_trap "$LCTL set_param \
25718                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25719         stack_trap "$LCTL set_param \
25720                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25721         stack_trap "$LCTL set_param \
25722                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25723
25724         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25725                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25726         lod_qos_prio_free=${lod_qos_prio_free%%%}
25727         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25728                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25729         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25730         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25731                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25732         stack_trap "do_nodes $mdts $LCTL set_param \
25733                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25734         stack_trap "do_nodes $mdts $LCTL set_param \
25735                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25736         stack_trap "do_nodes $mdts $LCTL set_param \
25737                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25738
25739         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25740         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25741
25742         testdir=$DIR/$tdir-s$stripe_count/rr
25743
25744         local stripe_index=$($LFS getstripe -m $testdir)
25745         local test_mkdir_rr=true
25746
25747         getfattr -d -m dmv -e hex $testdir | grep dmv
25748         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25749                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25750                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25751                         test_mkdir_rr=false
25752         fi
25753
25754         echo
25755         $test_mkdir_rr &&
25756                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25757                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25758
25759         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25760         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25761                 eval $mkdir_cmd $testdir/subdir$i ||
25762                         error "$mkdir_cmd subdir$i failed"
25763         done
25764
25765         for (( i = 0; i < $MDSCOUNT; i++ )); do
25766                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25767                 echo "$count directories created on MDT$i"
25768                 if $test_mkdir_rr; then
25769                         (( $count == 100 )) ||
25770                                 error "subdirs are not evenly distributed"
25771                 elif (( $i == $stripe_index )); then
25772                         (( $count == 100 * MDSCOUNT )) ||
25773                                 error "$count subdirs created on MDT$i"
25774                 else
25775                         (( $count == 0 )) ||
25776                                 error "$count subdirs created on MDT$i"
25777                 fi
25778
25779                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25780                         count=$($LFS getdirstripe $testdir/* |
25781                                 grep -c -P "^\s+$i\t")
25782                         echo "$count stripes created on MDT$i"
25783                         # deviation should < 5% of average
25784                         (( $count >= 95 * stripe_count &&
25785                            $count <= 105 * stripe_count)) ||
25786                                 error "stripes are not evenly distributed"
25787                 fi
25788         done
25789
25790         echo
25791         echo "Check for uneven MDTs: "
25792
25793         local ffree
25794         local bavail
25795         local max
25796         local min
25797         local max_index
25798         local min_index
25799         local tmp
25800
25801         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25802         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25803         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25804
25805         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25806         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25807         max_index=0
25808         min_index=0
25809         for ((i = 1; i < ${#ffree[@]}; i++)); do
25810                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25811                 if [ $tmp -gt $max ]; then
25812                         max=$tmp
25813                         max_index=$i
25814                 fi
25815                 if [ $tmp -lt $min ]; then
25816                         min=$tmp
25817                         min_index=$i
25818                 fi
25819         done
25820
25821         (( ${ffree[min_index]} > 0 )) ||
25822                 skip "no free files in MDT$min_index"
25823         (( ${ffree[min_index]} < 10000000 )) ||
25824                 skip "too many free files in MDT$min_index"
25825
25826         echo "MDT filesfree available: ${ffree[*]}"
25827         echo "MDT blocks available: ${bavail[*]}"
25828         echo "weight diff=$(((max - min) * 100 / min))%"
25829         echo
25830         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25831
25832         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25833         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25834         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25835         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25836         # decrease statfs age, so that it can be updated in time
25837         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25838         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25839
25840         sleep 1
25841
25842         testdir=$DIR/$tdir-s$stripe_count/qos
25843         local num=200
25844
25845         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25846         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25847                 eval $mkdir_cmd $testdir/subdir$i ||
25848                         error "$mkdir_cmd subdir$i failed"
25849         done
25850
25851         max=0
25852         for (( i = 0; i < $MDSCOUNT; i++ )); do
25853                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25854                 (( count > max )) && max=$count
25855                 echo "$count directories created on MDT$i"
25856         done
25857
25858         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25859
25860         # D-value should > 10% of averge
25861         (( max - min > num / 10 )) ||
25862                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25863
25864         # ditto for stripes
25865         if (( stripe_count > 1 )); then
25866                 max=0
25867                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25868                         count=$($LFS getdirstripe $testdir/* |
25869                                 grep -c -P "^\s+$i\t")
25870                         (( count > max )) && max=$count
25871                         echo "$count stripes created on MDT$i"
25872                 done
25873
25874                 min=$($LFS getdirstripe $testdir/* |
25875                         grep -c -P "^\s+$min_index\t")
25876                 (( max - min > num * stripe_count / 10 )) ||
25877                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25878         fi
25879 }
25880
25881 most_full_mdt() {
25882         local ffree
25883         local bavail
25884         local bsize
25885         local min
25886         local min_index
25887         local tmp
25888
25889         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25890         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25891         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25892
25893         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25894         min_index=0
25895         for ((i = 1; i < ${#ffree[@]}; i++)); do
25896                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25897                 (( tmp < min )) && min=$tmp && min_index=$i
25898         done
25899
25900         echo -n $min_index
25901 }
25902
25903 test_413a() {
25904         [ $MDSCOUNT -lt 2 ] &&
25905                 skip "We need at least 2 MDTs for this test"
25906
25907         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25908                 skip "Need server version at least 2.12.52"
25909
25910         local stripe_count
25911
25912         generate_uneven_mdts 100
25913         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25914                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25915                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25916                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25917                         error "mkdir failed"
25918                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25919         done
25920 }
25921 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25922
25923 test_413b() {
25924         [ $MDSCOUNT -lt 2 ] &&
25925                 skip "We need at least 2 MDTs for this test"
25926
25927         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25928                 skip "Need server version at least 2.12.52"
25929
25930         local testdir
25931         local stripe_count
25932
25933         generate_uneven_mdts 100
25934         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25935                 testdir=$DIR/$tdir-s$stripe_count
25936                 mkdir $testdir || error "mkdir $testdir failed"
25937                 mkdir $testdir/rr || error "mkdir rr failed"
25938                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25939                         error "mkdir qos failed"
25940                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25941                         $testdir/rr || error "setdirstripe rr failed"
25942                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25943                         error "setdirstripe failed"
25944                 test_qos_mkdir "mkdir" $stripe_count
25945         done
25946 }
25947 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25948
25949 test_413c() {
25950         (( $MDSCOUNT >= 2 )) ||
25951                 skip "We need at least 2 MDTs for this test"
25952
25953         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25954                 skip "Need server version at least 2.14.51"
25955
25956         local testdir
25957         local inherit
25958         local inherit_rr
25959
25960         testdir=$DIR/${tdir}-s1
25961         mkdir $testdir || error "mkdir $testdir failed"
25962         mkdir $testdir/rr || error "mkdir rr failed"
25963         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25964         # default max_inherit is -1, default max_inherit_rr is 0
25965         $LFS setdirstripe -D -c 1 $testdir/rr ||
25966                 error "setdirstripe rr failed"
25967         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25968                 error "setdirstripe qos failed"
25969         test_qos_mkdir "mkdir" 1
25970
25971         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25972         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25973         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25974         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25975         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25976
25977         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25978         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25979         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25980         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25981         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25982         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25983         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25984                 error "level2 shouldn't have default LMV" || true
25985 }
25986 run_test 413c "mkdir with default LMV max inherit rr"
25987
25988 test_413d() {
25989         (( MDSCOUNT >= 2 )) ||
25990                 skip "We need at least 2 MDTs for this test"
25991
25992         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25993                 skip "Need server version at least 2.14.51"
25994
25995         local lmv_qos_threshold_rr
25996
25997         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25998                 head -n1)
25999         stack_trap "$LCTL set_param \
26000                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26001
26002         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26003         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26004         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26005                 error "$tdir shouldn't have default LMV"
26006         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26007                 error "mkdir sub failed"
26008
26009         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26010
26011         (( count == 100 )) || error "$count subdirs on MDT0"
26012 }
26013 run_test 413d "inherit ROOT default LMV"
26014
26015 test_413e() {
26016         (( MDSCOUNT >= 2 )) ||
26017                 skip "We need at least 2 MDTs for this test"
26018         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26019                 skip "Need server version at least 2.14.55"
26020
26021         local testdir=$DIR/$tdir
26022         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26023         local max_inherit
26024         local sub_max_inherit
26025
26026         mkdir -p $testdir || error "failed to create $testdir"
26027
26028         # set default max-inherit to -1 if stripe count is 0 or 1
26029         $LFS setdirstripe -D -c 1 $testdir ||
26030                 error "failed to set default LMV"
26031         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26032         (( max_inherit == -1 )) ||
26033                 error "wrong max_inherit value $max_inherit"
26034
26035         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26036         $LFS setdirstripe -D -c -1 $testdir ||
26037                 error "failed to set default LMV"
26038         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26039         (( max_inherit > 0 )) ||
26040                 error "wrong max_inherit value $max_inherit"
26041
26042         # and the subdir will decrease the max_inherit by 1
26043         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26044         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26045         (( sub_max_inherit == max_inherit - 1)) ||
26046                 error "wrong max-inherit of subdir $sub_max_inherit"
26047
26048         # check specified --max-inherit and warning message
26049         stack_trap "rm -f $tmpfile"
26050         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26051                 error "failed to set default LMV"
26052         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26053         (( max_inherit == -1 )) ||
26054                 error "wrong max_inherit value $max_inherit"
26055
26056         # check the warning messages
26057         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26058                 error "failed to detect warning string"
26059         fi
26060 }
26061 run_test 413e "check default max-inherit value"
26062
26063 test_fs_dmv_inherit()
26064 {
26065         local testdir=$DIR/$tdir
26066
26067         local count
26068         local inherit
26069         local inherit_rr
26070
26071         for i in 1 2 3; do
26072                 mkdir $testdir || error "mkdir $testdir failed"
26073                 count=$($LFS getdirstripe -D -c $testdir)
26074                 (( count == 1 )) ||
26075                         error "$testdir default LMV count mismatch $count != 1"
26076                 inherit=$($LFS getdirstripe -D -X $testdir)
26077                 (( inherit == 3 - i )) ||
26078                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26079                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26080                 (( inherit_rr == 3 - i )) ||
26081                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26082                 testdir=$testdir/sub
26083         done
26084
26085         mkdir $testdir || error "mkdir $testdir failed"
26086         count=$($LFS getdirstripe -D -c $testdir)
26087         (( count == 0 )) ||
26088                 error "$testdir default LMV count not zero: $count"
26089 }
26090
26091 test_413f() {
26092         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26093
26094         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26095                 skip "Need server version at least 2.14.55"
26096
26097         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26098                 error "dump $DIR default LMV failed"
26099         stack_trap "setfattr --restore=$TMP/dmv.ea"
26100
26101         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26102                 error "set $DIR default LMV failed"
26103
26104         test_fs_dmv_inherit
26105 }
26106 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26107
26108 test_413g() {
26109         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26110
26111         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26112         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26113                 error "dump $DIR default LMV failed"
26114         stack_trap "setfattr --restore=$TMP/dmv.ea"
26115
26116         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26117                 error "set $DIR default LMV failed"
26118
26119         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26120                 error "mount $MOUNT2 failed"
26121         stack_trap "umount_client $MOUNT2"
26122
26123         local saved_DIR=$DIR
26124
26125         export DIR=$MOUNT2
26126
26127         stack_trap "export DIR=$saved_DIR"
26128
26129         # first check filesystem-wide default LMV inheritance
26130         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26131
26132         # then check subdirs are spread to all MDTs
26133         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26134
26135         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26136
26137         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26138 }
26139 run_test 413g "enforce ROOT default LMV on subdir mount"
26140
26141 test_413h() {
26142         (( MDSCOUNT >= 2 )) ||
26143                 skip "We need at least 2 MDTs for this test"
26144
26145         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26146                 skip "Need server version at least 2.15.50.6"
26147
26148         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26149
26150         stack_trap "$LCTL set_param \
26151                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26152         $LCTL set_param lmv.*.qos_maxage=1
26153
26154         local depth=5
26155         local rr_depth=4
26156         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26157         local count=$((MDSCOUNT * 20))
26158
26159         generate_uneven_mdts 50
26160
26161         mkdir -p $dir || error "mkdir $dir failed"
26162         stack_trap "rm -rf $dir"
26163         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26164                 --max-inherit-rr=$rr_depth $dir
26165
26166         for ((d=0; d < depth + 2; d++)); do
26167                 log "dir=$dir:"
26168                 for ((sub=0; sub < count; sub++)); do
26169                         mkdir $dir/d$sub
26170                 done
26171                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26172                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26173                 # subdirs within $rr_depth should be created round-robin
26174                 if (( d < rr_depth )); then
26175                         (( ${num[0]} != count )) ||
26176                                 error "all objects created on MDT ${num[1]}"
26177                 fi
26178
26179                 dir=$dir/d0
26180         done
26181 }
26182 run_test 413h "don't stick to parent for round-robin dirs"
26183
26184 test_413z() {
26185         local pids=""
26186         local subdir
26187         local pid
26188
26189         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26190                 unlinkmany $subdir/f. $TEST413_COUNT &
26191                 pids="$pids $!"
26192         done
26193
26194         for pid in $pids; do
26195                 wait $pid
26196         done
26197 }
26198 run_test 413z "413 test cleanup"
26199
26200 test_414() {
26201 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26202         $LCTL set_param fail_loc=0x80000521
26203         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26204         rm -f $DIR/$tfile
26205 }
26206 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26207
26208 test_415() {
26209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26210         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26211                 skip "Need server version at least 2.11.52"
26212
26213         # LU-11102
26214         local total
26215         local setattr_pid
26216         local start_time
26217         local end_time
26218         local duration
26219
26220         total=500
26221         # this test may be slow on ZFS
26222         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26223
26224         # though this test is designed for striped directory, let's test normal
26225         # directory too since lock is always saved as CoS lock.
26226         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26227         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26228
26229         (
26230                 while true; do
26231                         touch $DIR/$tdir
26232                 done
26233         ) &
26234         setattr_pid=$!
26235
26236         start_time=$(date +%s)
26237         for i in $(seq $total); do
26238                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26239                         > /dev/null
26240         done
26241         end_time=$(date +%s)
26242         duration=$((end_time - start_time))
26243
26244         kill -9 $setattr_pid
26245
26246         echo "rename $total files took $duration sec"
26247         [ $duration -lt 100 ] || error "rename took $duration sec"
26248 }
26249 run_test 415 "lock revoke is not missing"
26250
26251 test_416() {
26252         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26253                 skip "Need server version at least 2.11.55"
26254
26255         # define OBD_FAIL_OSD_TXN_START    0x19a
26256         do_facet mds1 lctl set_param fail_loc=0x19a
26257
26258         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26259
26260         true
26261 }
26262 run_test 416 "transaction start failure won't cause system hung"
26263
26264 cleanup_417() {
26265         trap 0
26266         do_nodes $(comma_list $(mdts_nodes)) \
26267                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26268         do_nodes $(comma_list $(mdts_nodes)) \
26269                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26270         do_nodes $(comma_list $(mdts_nodes)) \
26271                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26272 }
26273
26274 test_417() {
26275         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26276         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26277                 skip "Need MDS version at least 2.11.56"
26278
26279         trap cleanup_417 RETURN EXIT
26280
26281         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26282         do_nodes $(comma_list $(mdts_nodes)) \
26283                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26284         $LFS migrate -m 0 $DIR/$tdir.1 &&
26285                 error "migrate dir $tdir.1 should fail"
26286
26287         do_nodes $(comma_list $(mdts_nodes)) \
26288                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26289         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26290                 error "create remote dir $tdir.2 should fail"
26291
26292         do_nodes $(comma_list $(mdts_nodes)) \
26293                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26294         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26295                 error "create striped dir $tdir.3 should fail"
26296         true
26297 }
26298 run_test 417 "disable remote dir, striped dir and dir migration"
26299
26300 # Checks that the outputs of df [-i] and lfs df [-i] match
26301 #
26302 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26303 check_lfs_df() {
26304         local dir=$2
26305         local inodes
26306         local df_out
26307         local lfs_df_out
26308         local count
26309         local passed=false
26310
26311         # blocks or inodes
26312         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26313
26314         for count in {1..100}; do
26315                 do_nodes "$CLIENTS" \
26316                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26317                 sync; sleep 0.2
26318
26319                 # read the lines of interest
26320                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26321                         error "df $inodes $dir | tail -n +2 failed"
26322                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26323                         error "lfs df $inodes $dir | grep summary: failed"
26324
26325                 # skip first substrings of each output as they are different
26326                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26327                 # compare the two outputs
26328                 passed=true
26329                 #  skip "available" on MDT until LU-13997 is fixed.
26330                 #for i in {1..5}; do
26331                 for i in 1 2 4 5; do
26332                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26333                 done
26334                 $passed && break
26335         done
26336
26337         if ! $passed; then
26338                 df -P $inodes $dir
26339                 echo
26340                 lfs df $inodes $dir
26341                 error "df and lfs df $1 output mismatch: "      \
26342                       "df ${inodes}: ${df_out[*]}, "            \
26343                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26344         fi
26345 }
26346
26347 test_418() {
26348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26349
26350         local dir=$DIR/$tdir
26351         local numfiles=$((RANDOM % 4096 + 2))
26352         local numblocks=$((RANDOM % 256 + 1))
26353
26354         wait_delete_completed
26355         test_mkdir $dir
26356
26357         # check block output
26358         check_lfs_df blocks $dir
26359         # check inode output
26360         check_lfs_df inodes $dir
26361
26362         # create a single file and retest
26363         echo "Creating a single file and testing"
26364         createmany -o $dir/$tfile- 1 &>/dev/null ||
26365                 error "creating 1 file in $dir failed"
26366         check_lfs_df blocks $dir
26367         check_lfs_df inodes $dir
26368
26369         # create a random number of files
26370         echo "Creating $((numfiles - 1)) files and testing"
26371         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26372                 error "creating $((numfiles - 1)) files in $dir failed"
26373
26374         # write a random number of blocks to the first test file
26375         echo "Writing $numblocks 4K blocks and testing"
26376         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26377                 count=$numblocks &>/dev/null ||
26378                 error "dd to $dir/${tfile}-0 failed"
26379
26380         # retest
26381         check_lfs_df blocks $dir
26382         check_lfs_df inodes $dir
26383
26384         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26385                 error "unlinking $numfiles files in $dir failed"
26386 }
26387 run_test 418 "df and lfs df outputs match"
26388
26389 test_419()
26390 {
26391         local dir=$DIR/$tdir
26392
26393         mkdir -p $dir
26394         touch $dir/file
26395
26396         cancel_lru_locks mdc
26397
26398         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26399         $LCTL set_param fail_loc=0x1410
26400         cat $dir/file
26401         $LCTL set_param fail_loc=0
26402         rm -rf $dir
26403 }
26404 run_test 419 "Verify open file by name doesn't crash kernel"
26405
26406 test_420()
26407 {
26408         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26409                 skip "Need MDS version at least 2.12.53"
26410
26411         local SAVE_UMASK=$(umask)
26412         local dir=$DIR/$tdir
26413         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26414
26415         mkdir -p $dir
26416         umask 0000
26417         mkdir -m03777 $dir/testdir
26418         ls -dn $dir/testdir
26419         # Need to remove trailing '.' when SELinux is enabled
26420         local dirperms=$(ls -dn $dir/testdir |
26421                          awk '{ sub(/\.$/, "", $1); print $1}')
26422         [ $dirperms == "drwxrwsrwt" ] ||
26423                 error "incorrect perms on $dir/testdir"
26424
26425         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26426                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26427         ls -n $dir/testdir/testfile
26428         local fileperms=$(ls -n $dir/testdir/testfile |
26429                           awk '{ sub(/\.$/, "", $1); print $1}')
26430         [ $fileperms == "-rwxr-xr-x" ] ||
26431                 error "incorrect perms on $dir/testdir/testfile"
26432
26433         umask $SAVE_UMASK
26434 }
26435 run_test 420 "clear SGID bit on non-directories for non-members"
26436
26437 test_421a() {
26438         local cnt
26439         local fid1
26440         local fid2
26441
26442         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26443                 skip "Need MDS version at least 2.12.54"
26444
26445         test_mkdir $DIR/$tdir
26446         createmany -o $DIR/$tdir/f 3
26447         cnt=$(ls -1 $DIR/$tdir | wc -l)
26448         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26449
26450         fid1=$(lfs path2fid $DIR/$tdir/f1)
26451         fid2=$(lfs path2fid $DIR/$tdir/f2)
26452         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26453
26454         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26455         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26456
26457         cnt=$(ls -1 $DIR/$tdir | wc -l)
26458         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26459
26460         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26461         createmany -o $DIR/$tdir/f 3
26462         cnt=$(ls -1 $DIR/$tdir | wc -l)
26463         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26464
26465         fid1=$(lfs path2fid $DIR/$tdir/f1)
26466         fid2=$(lfs path2fid $DIR/$tdir/f2)
26467         echo "remove using fsname $FSNAME"
26468         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26469
26470         cnt=$(ls -1 $DIR/$tdir | wc -l)
26471         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26472 }
26473 run_test 421a "simple rm by fid"
26474
26475 test_421b() {
26476         local cnt
26477         local FID1
26478         local FID2
26479
26480         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26481                 skip "Need MDS version at least 2.12.54"
26482
26483         test_mkdir $DIR/$tdir
26484         createmany -o $DIR/$tdir/f 3
26485         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26486         MULTIPID=$!
26487
26488         FID1=$(lfs path2fid $DIR/$tdir/f1)
26489         FID2=$(lfs path2fid $DIR/$tdir/f2)
26490         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26491
26492         kill -USR1 $MULTIPID
26493         wait
26494
26495         cnt=$(ls $DIR/$tdir | wc -l)
26496         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26497 }
26498 run_test 421b "rm by fid on open file"
26499
26500 test_421c() {
26501         local cnt
26502         local FIDS
26503
26504         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26505                 skip "Need MDS version at least 2.12.54"
26506
26507         test_mkdir $DIR/$tdir
26508         createmany -o $DIR/$tdir/f 3
26509         touch $DIR/$tdir/$tfile
26510         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26511         cnt=$(ls -1 $DIR/$tdir | wc -l)
26512         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26513
26514         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26515         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26516
26517         cnt=$(ls $DIR/$tdir | wc -l)
26518         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26519 }
26520 run_test 421c "rm by fid against hardlinked files"
26521
26522 test_421d() {
26523         local cnt
26524         local FIDS
26525
26526         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26527                 skip "Need MDS version at least 2.12.54"
26528
26529         test_mkdir $DIR/$tdir
26530         createmany -o $DIR/$tdir/f 4097
26531         cnt=$(ls -1 $DIR/$tdir | wc -l)
26532         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26533
26534         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26535         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26536
26537         cnt=$(ls $DIR/$tdir | wc -l)
26538         rm -rf $DIR/$tdir
26539         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26540 }
26541 run_test 421d "rmfid en masse"
26542
26543 test_421e() {
26544         local cnt
26545         local FID
26546
26547         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26548         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26549                 skip "Need MDS version at least 2.12.54"
26550
26551         mkdir -p $DIR/$tdir
26552         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26553         createmany -o $DIR/$tdir/striped_dir/f 512
26554         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26555         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26556
26557         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26558                 sed "s/[/][^:]*://g")
26559         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26560
26561         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26562         rm -rf $DIR/$tdir
26563         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26564 }
26565 run_test 421e "rmfid in DNE"
26566
26567 test_421f() {
26568         local cnt
26569         local FID
26570
26571         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26572                 skip "Need MDS version at least 2.12.54"
26573
26574         test_mkdir $DIR/$tdir
26575         touch $DIR/$tdir/f
26576         cnt=$(ls -1 $DIR/$tdir | wc -l)
26577         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26578
26579         FID=$(lfs path2fid $DIR/$tdir/f)
26580         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26581         # rmfid should fail
26582         cnt=$(ls -1 $DIR/$tdir | wc -l)
26583         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26584
26585         chmod a+rw $DIR/$tdir
26586         ls -la $DIR/$tdir
26587         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26588         # rmfid should fail
26589         cnt=$(ls -1 $DIR/$tdir | wc -l)
26590         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26591
26592         rm -f $DIR/$tdir/f
26593         $RUNAS touch $DIR/$tdir/f
26594         FID=$(lfs path2fid $DIR/$tdir/f)
26595         echo "rmfid as root"
26596         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26597         cnt=$(ls -1 $DIR/$tdir | wc -l)
26598         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26599
26600         rm -f $DIR/$tdir/f
26601         $RUNAS touch $DIR/$tdir/f
26602         cnt=$(ls -1 $DIR/$tdir | wc -l)
26603         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26604         FID=$(lfs path2fid $DIR/$tdir/f)
26605         # rmfid w/o user_fid2path mount option should fail
26606         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26607         cnt=$(ls -1 $DIR/$tdir | wc -l)
26608         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26609
26610         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26611         stack_trap "rmdir $tmpdir"
26612         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26613                 error "failed to mount client'"
26614         stack_trap "umount_client $tmpdir"
26615
26616         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26617         # rmfid should succeed
26618         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26619         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26620
26621         # rmfid shouldn't allow to remove files due to dir's permission
26622         chmod a+rwx $tmpdir/$tdir
26623         touch $tmpdir/$tdir/f
26624         ls -la $tmpdir/$tdir
26625         FID=$(lfs path2fid $tmpdir/$tdir/f)
26626         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26627         return 0
26628 }
26629 run_test 421f "rmfid checks permissions"
26630
26631 test_421g() {
26632         local cnt
26633         local FIDS
26634
26635         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26636         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26637                 skip "Need MDS version at least 2.12.54"
26638
26639         mkdir -p $DIR/$tdir
26640         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26641         createmany -o $DIR/$tdir/striped_dir/f 512
26642         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26643         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26644
26645         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26646                 sed "s/[/][^:]*://g")
26647
26648         rm -f $DIR/$tdir/striped_dir/f1*
26649         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26650         removed=$((512 - cnt))
26651
26652         # few files have been just removed, so we expect
26653         # rmfid to fail on their fids
26654         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26655         [ $removed != $errors ] && error "$errors != $removed"
26656
26657         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26658         rm -rf $DIR/$tdir
26659         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26660 }
26661 run_test 421g "rmfid to return errors properly"
26662
26663 test_422() {
26664         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26665         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26666         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26667         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26668         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26669
26670         local amc=$(at_max_get client)
26671         local amo=$(at_max_get mds1)
26672         local timeout=`lctl get_param -n timeout`
26673
26674         at_max_set 0 client
26675         at_max_set 0 mds1
26676
26677 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26678         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26679                         fail_val=$(((2*timeout + 10)*1000))
26680         touch $DIR/$tdir/d3/file &
26681         sleep 2
26682 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26683         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26684                         fail_val=$((2*timeout + 5))
26685         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26686         local pid=$!
26687         sleep 1
26688         kill -9 $pid
26689         sleep $((2 * timeout))
26690         echo kill $pid
26691         kill -9 $pid
26692         lctl mark touch
26693         touch $DIR/$tdir/d2/file3
26694         touch $DIR/$tdir/d2/file4
26695         touch $DIR/$tdir/d2/file5
26696
26697         wait
26698         at_max_set $amc client
26699         at_max_set $amo mds1
26700
26701         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26702         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26703                 error "Watchdog is always throttled"
26704 }
26705 run_test 422 "kill a process with RPC in progress"
26706
26707 stat_test() {
26708     df -h $MOUNT &
26709     df -h $MOUNT &
26710     df -h $MOUNT &
26711     df -h $MOUNT &
26712     df -h $MOUNT &
26713     df -h $MOUNT &
26714 }
26715
26716 test_423() {
26717     local _stats
26718     # ensure statfs cache is expired
26719     sleep 2;
26720
26721     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26722     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26723
26724     return 0
26725 }
26726 run_test 423 "statfs should return a right data"
26727
26728 test_424() {
26729 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26730         $LCTL set_param fail_loc=0x80000522
26731         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26732         rm -f $DIR/$tfile
26733 }
26734 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26735
26736 test_425() {
26737         test_mkdir -c -1 $DIR/$tdir
26738         $LFS setstripe -c -1 $DIR/$tdir
26739
26740         lru_resize_disable "" 100
26741         stack_trap "lru_resize_enable" EXIT
26742
26743         sleep 5
26744
26745         for i in $(seq $((MDSCOUNT * 125))); do
26746                 local t=$DIR/$tdir/$tfile_$i
26747
26748                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26749                         error_noexit "Create file $t"
26750         done
26751         stack_trap "rm -rf $DIR/$tdir" EXIT
26752
26753         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26754                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26755                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26756
26757                 [ $lock_count -le $lru_size ] ||
26758                         error "osc lock count $lock_count > lru size $lru_size"
26759         done
26760
26761         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26762                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26763                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26764
26765                 [ $lock_count -le $lru_size ] ||
26766                         error "mdc lock count $lock_count > lru size $lru_size"
26767         done
26768 }
26769 run_test 425 "lock count should not exceed lru size"
26770
26771 test_426() {
26772         splice-test -r $DIR/$tfile
26773         splice-test -rd $DIR/$tfile
26774         splice-test $DIR/$tfile
26775         splice-test -d $DIR/$tfile
26776 }
26777 run_test 426 "splice test on Lustre"
26778
26779 test_427() {
26780         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26781         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26782                 skip "Need MDS version at least 2.12.4"
26783         local log
26784
26785         mkdir $DIR/$tdir
26786         mkdir $DIR/$tdir/1
26787         mkdir $DIR/$tdir/2
26788         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26789         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26790
26791         $LFS getdirstripe $DIR/$tdir/1/dir
26792
26793         #first setfattr for creating updatelog
26794         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26795
26796 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26797         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26798         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26799         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26800
26801         sleep 2
26802         fail mds2
26803         wait_recovery_complete mds2 $((2*TIMEOUT))
26804
26805         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26806         echo $log | grep "get update log failed" &&
26807                 error "update log corruption is detected" || true
26808 }
26809 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26810
26811 test_428() {
26812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26813         local cache_limit=$CACHE_MAX
26814
26815         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26816         $LCTL set_param -n llite.*.max_cached_mb=64
26817
26818         mkdir $DIR/$tdir
26819         $LFS setstripe -c 1 $DIR/$tdir
26820         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26821         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26822         #test write
26823         for f in $(seq 4); do
26824                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26825         done
26826         wait
26827
26828         cancel_lru_locks osc
26829         # Test read
26830         for f in $(seq 4); do
26831                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26832         done
26833         wait
26834 }
26835 run_test 428 "large block size IO should not hang"
26836
26837 test_429() { # LU-7915 / LU-10948
26838         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26839         local testfile=$DIR/$tfile
26840         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26841         local new_flag=1
26842         local first_rpc
26843         local second_rpc
26844         local third_rpc
26845
26846         $LCTL get_param $ll_opencache_threshold_count ||
26847                 skip "client does not have opencache parameter"
26848
26849         set_opencache $new_flag
26850         stack_trap "restore_opencache"
26851         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26852                 error "enable opencache failed"
26853         touch $testfile
26854         # drop MDC DLM locks
26855         cancel_lru_locks mdc
26856         # clear MDC RPC stats counters
26857         $LCTL set_param $mdc_rpcstats=clear
26858
26859         # According to the current implementation, we need to run 3 times
26860         # open & close file to verify if opencache is enabled correctly.
26861         # 1st, RPCs are sent for lookup/open and open handle is released on
26862         #      close finally.
26863         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26864         #      so open handle won't be released thereafter.
26865         # 3rd, No RPC is sent out.
26866         $MULTIOP $testfile oc || error "multiop failed"
26867         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26868         echo "1st: $first_rpc RPCs in flight"
26869
26870         $MULTIOP $testfile oc || error "multiop failed"
26871         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26872         echo "2nd: $second_rpc RPCs in flight"
26873
26874         $MULTIOP $testfile oc || error "multiop failed"
26875         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26876         echo "3rd: $third_rpc RPCs in flight"
26877
26878         #verify no MDC RPC is sent
26879         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26880 }
26881 run_test 429 "verify if opencache flag on client side does work"
26882
26883 lseek_test_430() {
26884         local offset
26885         local file=$1
26886
26887         # data at [200K, 400K)
26888         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26889                 error "256K->512K dd fails"
26890         # data at [2M, 3M)
26891         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26892                 error "2M->3M dd fails"
26893         # data at [4M, 5M)
26894         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26895                 error "4M->5M dd fails"
26896         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26897         # start at first component hole #1
26898         printf "Seeking hole from 1000 ... "
26899         offset=$(lseek_test -l 1000 $file)
26900         echo $offset
26901         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26902         printf "Seeking data from 1000 ... "
26903         offset=$(lseek_test -d 1000 $file)
26904         echo $offset
26905         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26906
26907         # start at first component data block
26908         printf "Seeking hole from 300000 ... "
26909         offset=$(lseek_test -l 300000 $file)
26910         echo $offset
26911         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26912         printf "Seeking data from 300000 ... "
26913         offset=$(lseek_test -d 300000 $file)
26914         echo $offset
26915         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26916
26917         # start at the first component but beyond end of object size
26918         printf "Seeking hole from 1000000 ... "
26919         offset=$(lseek_test -l 1000000 $file)
26920         echo $offset
26921         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26922         printf "Seeking data from 1000000 ... "
26923         offset=$(lseek_test -d 1000000 $file)
26924         echo $offset
26925         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26926
26927         # start at second component stripe 2 (empty file)
26928         printf "Seeking hole from 1500000 ... "
26929         offset=$(lseek_test -l 1500000 $file)
26930         echo $offset
26931         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26932         printf "Seeking data from 1500000 ... "
26933         offset=$(lseek_test -d 1500000 $file)
26934         echo $offset
26935         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26936
26937         # start at second component stripe 1 (all data)
26938         printf "Seeking hole from 3000000 ... "
26939         offset=$(lseek_test -l 3000000 $file)
26940         echo $offset
26941         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26942         printf "Seeking data from 3000000 ... "
26943         offset=$(lseek_test -d 3000000 $file)
26944         echo $offset
26945         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26946
26947         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26948                 error "2nd dd fails"
26949         echo "Add data block at 640K...1280K"
26950
26951         # start at before new data block, in hole
26952         printf "Seeking hole from 600000 ... "
26953         offset=$(lseek_test -l 600000 $file)
26954         echo $offset
26955         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26956         printf "Seeking data from 600000 ... "
26957         offset=$(lseek_test -d 600000 $file)
26958         echo $offset
26959         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26960
26961         # start at the first component new data block
26962         printf "Seeking hole from 1000000 ... "
26963         offset=$(lseek_test -l 1000000 $file)
26964         echo $offset
26965         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26966         printf "Seeking data from 1000000 ... "
26967         offset=$(lseek_test -d 1000000 $file)
26968         echo $offset
26969         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26970
26971         # start at second component stripe 2, new data
26972         printf "Seeking hole from 1200000 ... "
26973         offset=$(lseek_test -l 1200000 $file)
26974         echo $offset
26975         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26976         printf "Seeking data from 1200000 ... "
26977         offset=$(lseek_test -d 1200000 $file)
26978         echo $offset
26979         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26980
26981         # start beyond file end
26982         printf "Using offset > filesize ... "
26983         lseek_test -l 4000000 $file && error "lseek should fail"
26984         printf "Using offset > filesize ... "
26985         lseek_test -d 4000000 $file && error "lseek should fail"
26986
26987         printf "Done\n\n"
26988 }
26989
26990 test_430a() {
26991         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26992                 skip "MDT does not support SEEK_HOLE"
26993
26994         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26995                 skip "OST does not support SEEK_HOLE"
26996
26997         local file=$DIR/$tdir/$tfile
26998
26999         mkdir -p $DIR/$tdir
27000
27001         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27002         # OST stripe #1 will have continuous data at [1M, 3M)
27003         # OST stripe #2 is empty
27004         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27005         lseek_test_430 $file
27006         rm $file
27007         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27008         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27009         lseek_test_430 $file
27010         rm $file
27011         $LFS setstripe -c2 -S 512K $file
27012         echo "Two stripes, stripe size 512K"
27013         lseek_test_430 $file
27014         rm $file
27015         # FLR with stale mirror
27016         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27017                        -N -c2 -S 1M $file
27018         echo "Mirrored file:"
27019         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27020         echo "Plain 2 stripes 1M"
27021         lseek_test_430 $file
27022         rm $file
27023 }
27024 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27025
27026 test_430b() {
27027         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27028                 skip "OST does not support SEEK_HOLE"
27029
27030         local offset
27031         local file=$DIR/$tdir/$tfile
27032
27033         mkdir -p $DIR/$tdir
27034         # Empty layout lseek should fail
27035         $MCREATE $file
27036         # seek from 0
27037         printf "Seeking hole from 0 ... "
27038         lseek_test -l 0 $file && error "lseek should fail"
27039         printf "Seeking data from 0 ... "
27040         lseek_test -d 0 $file && error "lseek should fail"
27041         rm $file
27042
27043         # 1M-hole file
27044         $LFS setstripe -E 1M -c2 -E eof $file
27045         $TRUNCATE $file 1048576
27046         printf "Seeking hole from 1000000 ... "
27047         offset=$(lseek_test -l 1000000 $file)
27048         echo $offset
27049         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27050         printf "Seeking data from 1000000 ... "
27051         lseek_test -d 1000000 $file && error "lseek should fail"
27052         rm $file
27053
27054         # full component followed by non-inited one
27055         $LFS setstripe -E 1M -c2 -E eof $file
27056         dd if=/dev/urandom of=$file bs=1M count=1
27057         printf "Seeking hole from 1000000 ... "
27058         offset=$(lseek_test -l 1000000 $file)
27059         echo $offset
27060         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27061         printf "Seeking hole from 1048576 ... "
27062         lseek_test -l 1048576 $file && error "lseek should fail"
27063         # init second component and truncate back
27064         echo "123" >> $file
27065         $TRUNCATE $file 1048576
27066         printf "Seeking hole from 1000000 ... "
27067         offset=$(lseek_test -l 1000000 $file)
27068         echo $offset
27069         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27070         printf "Seeking hole from 1048576 ... "
27071         lseek_test -l 1048576 $file && error "lseek should fail"
27072         # boundary checks for big values
27073         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27074         offset=$(lseek_test -d 0 $file.10g)
27075         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27076         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27077         offset=$(lseek_test -d 0 $file.100g)
27078         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27079         return 0
27080 }
27081 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27082
27083 test_430c() {
27084         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27085                 skip "OST does not support SEEK_HOLE"
27086
27087         local file=$DIR/$tdir/$tfile
27088         local start
27089
27090         mkdir -p $DIR/$tdir
27091         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27092
27093         # cp version 8.33+ prefers lseek over fiemap
27094         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27095                 start=$SECONDS
27096                 time cp $file /dev/null
27097                 (( SECONDS - start < 5 )) ||
27098                         error "cp: too long runtime $((SECONDS - start))"
27099
27100         fi
27101         # tar version 1.29+ supports SEEK_HOLE/DATA
27102         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27103                 start=$SECONDS
27104                 time tar cS $file - | cat > /dev/null
27105                 (( SECONDS - start < 5 )) ||
27106                         error "tar: too long runtime $((SECONDS - start))"
27107         fi
27108 }
27109 run_test 430c "lseek: external tools check"
27110
27111 test_431() { # LU-14187
27112         local file=$DIR/$tdir/$tfile
27113
27114         mkdir -p $DIR/$tdir
27115         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27116         dd if=/dev/urandom of=$file bs=4k count=1
27117         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27118         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27119         #define OBD_FAIL_OST_RESTART_IO 0x251
27120         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27121         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27122         cp $file $file.0
27123         cancel_lru_locks
27124         sync_all_data
27125         echo 3 > /proc/sys/vm/drop_caches
27126         diff  $file $file.0 || error "data diff"
27127 }
27128 run_test 431 "Restart transaction for IO"
27129
27130 cleanup_test_432() {
27131         do_facet mgs $LCTL nodemap_activate 0
27132         wait_nm_sync active
27133 }
27134
27135 test_432() {
27136         local tmpdir=$TMP/dir432
27137
27138         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27139                 skip "Need MDS version at least 2.14.52"
27140
27141         stack_trap cleanup_test_432 EXIT
27142         mkdir $DIR/$tdir
27143         mkdir $tmpdir
27144
27145         do_facet mgs $LCTL nodemap_activate 1
27146         wait_nm_sync active
27147         do_facet mgs $LCTL nodemap_modify --name default \
27148                 --property admin --value 1
27149         do_facet mgs $LCTL nodemap_modify --name default \
27150                 --property trusted --value 1
27151         cancel_lru_locks mdc
27152         wait_nm_sync default admin_nodemap
27153         wait_nm_sync default trusted_nodemap
27154
27155         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27156                grep -ci "Operation not permitted") -ne 0 ]; then
27157                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27158         fi
27159 }
27160 run_test 432 "mv dir from outside Lustre"
27161
27162 test_433() {
27163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27164
27165         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27166                 skip "inode cache not supported"
27167
27168         $LCTL set_param llite.*.inode_cache=0
27169         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27170
27171         local count=256
27172         local before
27173         local after
27174
27175         cancel_lru_locks mdc
27176         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27177         createmany -m $DIR/$tdir/f $count
27178         createmany -d $DIR/$tdir/d $count
27179         ls -l $DIR/$tdir > /dev/null
27180         stack_trap "rm -rf $DIR/$tdir"
27181
27182         before=$(num_objects)
27183         cancel_lru_locks mdc
27184         after=$(num_objects)
27185
27186         # sometimes even @before is less than 2 * count
27187         while (( before - after < count )); do
27188                 sleep 1
27189                 after=$(num_objects)
27190                 wait=$((wait + 1))
27191                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27192                 if (( wait > 60 )); then
27193                         error "inode slab grew from $before to $after"
27194                 fi
27195         done
27196
27197         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27198 }
27199 run_test 433 "ldlm lock cancel releases dentries and inodes"
27200
27201 prep_801() {
27202         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27203         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27204                 skip "Need server version at least 2.9.55"
27205
27206         start_full_debug_logging
27207 }
27208
27209 post_801() {
27210         stop_full_debug_logging
27211 }
27212
27213 barrier_stat() {
27214         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27215                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27216                            awk '/The barrier for/ { print $7 }')
27217                 echo $st
27218         else
27219                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27220                 echo \'$st\'
27221         fi
27222 }
27223
27224 barrier_expired() {
27225         local expired
27226
27227         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27228                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27229                           awk '/will be expired/ { print $7 }')
27230         else
27231                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27232         fi
27233
27234         echo $expired
27235 }
27236
27237 test_801a() {
27238         prep_801
27239
27240         echo "Start barrier_freeze at: $(date)"
27241         #define OBD_FAIL_BARRIER_DELAY          0x2202
27242         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27243         # Do not reduce barrier time - See LU-11873
27244         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27245
27246         sleep 2
27247         local b_status=$(barrier_stat)
27248         echo "Got barrier status at: $(date)"
27249         [ "$b_status" = "'freezing_p1'" ] ||
27250                 error "(1) unexpected barrier status $b_status"
27251
27252         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27253         wait
27254         b_status=$(barrier_stat)
27255         [ "$b_status" = "'frozen'" ] ||
27256                 error "(2) unexpected barrier status $b_status"
27257
27258         local expired=$(barrier_expired)
27259         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27260         sleep $((expired + 3))
27261
27262         b_status=$(barrier_stat)
27263         [ "$b_status" = "'expired'" ] ||
27264                 error "(3) unexpected barrier status $b_status"
27265
27266         # Do not reduce barrier time - See LU-11873
27267         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27268                 error "(4) fail to freeze barrier"
27269
27270         b_status=$(barrier_stat)
27271         [ "$b_status" = "'frozen'" ] ||
27272                 error "(5) unexpected barrier status $b_status"
27273
27274         echo "Start barrier_thaw at: $(date)"
27275         #define OBD_FAIL_BARRIER_DELAY          0x2202
27276         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27277         do_facet mgs $LCTL barrier_thaw $FSNAME &
27278
27279         sleep 2
27280         b_status=$(barrier_stat)
27281         echo "Got barrier status at: $(date)"
27282         [ "$b_status" = "'thawing'" ] ||
27283                 error "(6) unexpected barrier status $b_status"
27284
27285         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27286         wait
27287         b_status=$(barrier_stat)
27288         [ "$b_status" = "'thawed'" ] ||
27289                 error "(7) unexpected barrier status $b_status"
27290
27291         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27292         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27293         do_facet mgs $LCTL barrier_freeze $FSNAME
27294
27295         b_status=$(barrier_stat)
27296         [ "$b_status" = "'failed'" ] ||
27297                 error "(8) unexpected barrier status $b_status"
27298
27299         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27300         do_facet mgs $LCTL barrier_thaw $FSNAME
27301
27302         post_801
27303 }
27304 run_test 801a "write barrier user interfaces and stat machine"
27305
27306 test_801b() {
27307         prep_801
27308
27309         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27310         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27311         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27312         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27313         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27314
27315         cancel_lru_locks mdc
27316
27317         # 180 seconds should be long enough
27318         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27319
27320         local b_status=$(barrier_stat)
27321         [ "$b_status" = "'frozen'" ] ||
27322                 error "(6) unexpected barrier status $b_status"
27323
27324         mkdir $DIR/$tdir/d0/d10 &
27325         mkdir_pid=$!
27326
27327         touch $DIR/$tdir/d1/f13 &
27328         touch_pid=$!
27329
27330         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27331         ln_pid=$!
27332
27333         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27334         mv_pid=$!
27335
27336         rm -f $DIR/$tdir/d4/f12 &
27337         rm_pid=$!
27338
27339         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27340
27341         # To guarantee taht the 'stat' is not blocked
27342         b_status=$(barrier_stat)
27343         [ "$b_status" = "'frozen'" ] ||
27344                 error "(8) unexpected barrier status $b_status"
27345
27346         # let above commands to run at background
27347         sleep 5
27348
27349         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27350         ps -p $touch_pid || error "(10) touch should be blocked"
27351         ps -p $ln_pid || error "(11) link should be blocked"
27352         ps -p $mv_pid || error "(12) rename should be blocked"
27353         ps -p $rm_pid || error "(13) unlink should be blocked"
27354
27355         b_status=$(barrier_stat)
27356         [ "$b_status" = "'frozen'" ] ||
27357                 error "(14) unexpected barrier status $b_status"
27358
27359         do_facet mgs $LCTL barrier_thaw $FSNAME
27360         b_status=$(barrier_stat)
27361         [ "$b_status" = "'thawed'" ] ||
27362                 error "(15) unexpected barrier status $b_status"
27363
27364         wait $mkdir_pid || error "(16) mkdir should succeed"
27365         wait $touch_pid || error "(17) touch should succeed"
27366         wait $ln_pid || error "(18) link should succeed"
27367         wait $mv_pid || error "(19) rename should succeed"
27368         wait $rm_pid || error "(20) unlink should succeed"
27369
27370         post_801
27371 }
27372 run_test 801b "modification will be blocked by write barrier"
27373
27374 test_801c() {
27375         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27376
27377         prep_801
27378
27379         stop mds2 || error "(1) Fail to stop mds2"
27380
27381         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27382
27383         local b_status=$(barrier_stat)
27384         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27385                 do_facet mgs $LCTL barrier_thaw $FSNAME
27386                 error "(2) unexpected barrier status $b_status"
27387         }
27388
27389         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27390                 error "(3) Fail to rescan barrier bitmap"
27391
27392         # Do not reduce barrier time - See LU-11873
27393         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27394
27395         b_status=$(barrier_stat)
27396         [ "$b_status" = "'frozen'" ] ||
27397                 error "(4) unexpected barrier status $b_status"
27398
27399         do_facet mgs $LCTL barrier_thaw $FSNAME
27400         b_status=$(barrier_stat)
27401         [ "$b_status" = "'thawed'" ] ||
27402                 error "(5) unexpected barrier status $b_status"
27403
27404         local devname=$(mdsdevname 2)
27405
27406         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27407
27408         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27409                 error "(7) Fail to rescan barrier bitmap"
27410
27411         post_801
27412 }
27413 run_test 801c "rescan barrier bitmap"
27414
27415 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27416 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27417 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27418 saved_MOUNT_OPTS=$MOUNT_OPTS
27419
27420 cleanup_802a() {
27421         trap 0
27422
27423         stopall
27424         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27425         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27426         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27427         MOUNT_OPTS=$saved_MOUNT_OPTS
27428         setupall
27429 }
27430
27431 test_802a() {
27432         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27433         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27434         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27435                 skip "Need server version at least 2.9.55"
27436
27437         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27438
27439         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27440
27441         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27442                 error "(2) Fail to copy"
27443
27444         trap cleanup_802a EXIT
27445
27446         # sync by force before remount as readonly
27447         sync; sync_all_data; sleep 3; sync_all_data
27448
27449         stopall
27450
27451         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27452         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27453         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27454
27455         echo "Mount the server as read only"
27456         setupall server_only || error "(3) Fail to start servers"
27457
27458         echo "Mount client without ro should fail"
27459         mount_client $MOUNT &&
27460                 error "(4) Mount client without 'ro' should fail"
27461
27462         echo "Mount client with ro should succeed"
27463         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27464         mount_client $MOUNT ||
27465                 error "(5) Mount client with 'ro' should succeed"
27466
27467         echo "Modify should be refused"
27468         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27469
27470         echo "Read should be allowed"
27471         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27472                 error "(7) Read should succeed under ro mode"
27473
27474         cleanup_802a
27475 }
27476 run_test 802a "simulate readonly device"
27477
27478 test_802b() {
27479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27480         remote_mds_nodsh && skip "remote MDS with nodsh"
27481
27482         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27483                 skip "readonly option not available"
27484
27485         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27486
27487         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27488                 error "(2) Fail to copy"
27489
27490         # write back all cached data before setting MDT to readonly
27491         cancel_lru_locks
27492         sync_all_data
27493
27494         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27495         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27496
27497         echo "Modify should be refused"
27498         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27499
27500         echo "Read should be allowed"
27501         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27502                 error "(7) Read should succeed under ro mode"
27503
27504         # disable readonly
27505         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27506 }
27507 run_test 802b "be able to set MDTs to readonly"
27508
27509 test_803a() {
27510         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27511         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27512                 skip "MDS needs to be newer than 2.10.54"
27513
27514         mkdir_on_mdt0 $DIR/$tdir
27515         # Create some objects on all MDTs to trigger related logs objects
27516         for idx in $(seq $MDSCOUNT); do
27517                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27518                         $DIR/$tdir/dir${idx} ||
27519                         error "Fail to create $DIR/$tdir/dir${idx}"
27520         done
27521
27522         sync; sleep 3
27523         wait_delete_completed # ensure old test cleanups are finished
27524         echo "before create:"
27525         $LFS df -i $MOUNT
27526         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27527
27528         for i in {1..10}; do
27529                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27530                         error "Fail to create $DIR/$tdir/foo$i"
27531         done
27532
27533         sync; sleep 3
27534         echo "after create:"
27535         $LFS df -i $MOUNT
27536         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27537
27538         # allow for an llog to be cleaned up during the test
27539         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27540                 error "before ($before_used) + 10 > after ($after_used)"
27541
27542         for i in {1..10}; do
27543                 rm -rf $DIR/$tdir/foo$i ||
27544                         error "Fail to remove $DIR/$tdir/foo$i"
27545         done
27546
27547         sleep 3 # avoid MDT return cached statfs
27548         wait_delete_completed
27549         echo "after unlink:"
27550         $LFS df -i $MOUNT
27551         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27552
27553         # allow for an llog to be created during the test
27554         [ $after_used -le $((before_used + 1)) ] ||
27555                 error "after ($after_used) > before ($before_used) + 1"
27556 }
27557 run_test 803a "verify agent object for remote object"
27558
27559 test_803b() {
27560         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27561         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27562                 skip "MDS needs to be newer than 2.13.56"
27563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27564
27565         for i in $(seq 0 $((MDSCOUNT - 1))); do
27566                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27567         done
27568
27569         local before=0
27570         local after=0
27571
27572         local tmp
27573
27574         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27575         for i in $(seq 0 $((MDSCOUNT - 1))); do
27576                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27577                         awk '/getattr/ { print $2 }')
27578                 before=$((before + tmp))
27579         done
27580         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27581         for i in $(seq 0 $((MDSCOUNT - 1))); do
27582                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27583                         awk '/getattr/ { print $2 }')
27584                 after=$((after + tmp))
27585         done
27586
27587         [ $before -eq $after ] || error "getattr count $before != $after"
27588 }
27589 run_test 803b "remote object can getattr from cache"
27590
27591 test_804() {
27592         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27593         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27594                 skip "MDS needs to be newer than 2.10.54"
27595         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27596
27597         mkdir -p $DIR/$tdir
27598         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27599                 error "Fail to create $DIR/$tdir/dir0"
27600
27601         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27602         local dev=$(mdsdevname 2)
27603
27604         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27605                 grep ${fid} || error "NOT found agent entry for dir0"
27606
27607         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27608                 error "Fail to create $DIR/$tdir/dir1"
27609
27610         touch $DIR/$tdir/dir1/foo0 ||
27611                 error "Fail to create $DIR/$tdir/dir1/foo0"
27612         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27613         local rc=0
27614
27615         for idx in $(seq $MDSCOUNT); do
27616                 dev=$(mdsdevname $idx)
27617                 do_facet mds${idx} \
27618                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27619                         grep ${fid} && rc=$idx
27620         done
27621
27622         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27623                 error "Fail to rename foo0 to foo1"
27624         if [ $rc -eq 0 ]; then
27625                 for idx in $(seq $MDSCOUNT); do
27626                         dev=$(mdsdevname $idx)
27627                         do_facet mds${idx} \
27628                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27629                         grep ${fid} && rc=$idx
27630                 done
27631         fi
27632
27633         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27634                 error "Fail to rename foo1 to foo2"
27635         if [ $rc -eq 0 ]; then
27636                 for idx in $(seq $MDSCOUNT); do
27637                         dev=$(mdsdevname $idx)
27638                         do_facet mds${idx} \
27639                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27640                         grep ${fid} && rc=$idx
27641                 done
27642         fi
27643
27644         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27645
27646         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27647                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27648         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27649                 error "Fail to rename foo2 to foo0"
27650         unlink $DIR/$tdir/dir1/foo0 ||
27651                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27652         rm -rf $DIR/$tdir/dir0 ||
27653                 error "Fail to rm $DIR/$tdir/dir0"
27654
27655         for idx in $(seq $MDSCOUNT); do
27656                 rc=0
27657
27658                 stop mds${idx}
27659                 dev=$(mdsdevname $idx)
27660                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27661                         rc=$?
27662                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27663                         error "mount mds$idx failed"
27664                 df $MOUNT > /dev/null 2>&1
27665
27666                 # e2fsck should not return error
27667                 [ $rc -eq 0 ] ||
27668                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27669         done
27670 }
27671 run_test 804 "verify agent entry for remote entry"
27672
27673 cleanup_805() {
27674         do_facet $SINGLEMDS zfs set quota=$old $fsset
27675         unlinkmany $DIR/$tdir/f- 1000000
27676         trap 0
27677 }
27678
27679 test_805() {
27680         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27681         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27682         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27683                 skip "netfree not implemented before 0.7"
27684         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27685                 skip "Need MDS version at least 2.10.57"
27686
27687         local fsset
27688         local freekb
27689         local usedkb
27690         local old
27691         local quota
27692         local pref="osd-zfs.$FSNAME-MDT0000."
27693
27694         # limit available space on MDS dataset to meet nospace issue
27695         # quickly. then ZFS 0.7.2 can use reserved space if asked
27696         # properly (using netfree flag in osd_declare_destroy()
27697         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27698         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27699                 gawk '{print $3}')
27700         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27701         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27702         let "usedkb=usedkb-freekb"
27703         let "freekb=freekb/2"
27704         if let "freekb > 5000"; then
27705                 let "freekb=5000"
27706         fi
27707         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27708         trap cleanup_805 EXIT
27709         mkdir_on_mdt0 $DIR/$tdir
27710         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27711                 error "Can't set PFL layout"
27712         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27713         rm -rf $DIR/$tdir || error "not able to remove"
27714         do_facet $SINGLEMDS zfs set quota=$old $fsset
27715         trap 0
27716 }
27717 run_test 805 "ZFS can remove from full fs"
27718
27719 # Size-on-MDS test
27720 check_lsom_data()
27721 {
27722         local file=$1
27723         local expect=$(stat -c %s $file)
27724
27725         check_lsom_size $1 $expect
27726
27727         local blocks=$($LFS getsom -b $file)
27728         expect=$(stat -c %b $file)
27729         [[ $blocks == $expect ]] ||
27730                 error "$file expected blocks: $expect, got: $blocks"
27731 }
27732
27733 check_lsom_size()
27734 {
27735         local size
27736         local expect=$2
27737
27738         cancel_lru_locks mdc
27739
27740         size=$($LFS getsom -s $1)
27741         [[ $size == $expect ]] ||
27742                 error "$file expected size: $expect, got: $size"
27743 }
27744
27745 test_806() {
27746         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27747                 skip "Need MDS version at least 2.11.52"
27748
27749         local bs=1048576
27750
27751         touch $DIR/$tfile || error "touch $tfile failed"
27752
27753         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27754         save_lustre_params client "llite.*.xattr_cache" > $save
27755         lctl set_param llite.*.xattr_cache=0
27756         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27757
27758         # single-threaded write
27759         echo "Test SOM for single-threaded write"
27760         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27761                 error "write $tfile failed"
27762         check_lsom_size $DIR/$tfile $bs
27763
27764         local num=32
27765         local size=$(($num * $bs))
27766         local offset=0
27767         local i
27768
27769         echo "Test SOM for single client multi-threaded($num) write"
27770         $TRUNCATE $DIR/$tfile 0
27771         for ((i = 0; i < $num; i++)); do
27772                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27773                 local pids[$i]=$!
27774                 offset=$((offset + $bs))
27775         done
27776         for (( i=0; i < $num; i++ )); do
27777                 wait ${pids[$i]}
27778         done
27779         check_lsom_size $DIR/$tfile $size
27780
27781         $TRUNCATE $DIR/$tfile 0
27782         for ((i = 0; i < $num; i++)); do
27783                 offset=$((offset - $bs))
27784                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27785                 local pids[$i]=$!
27786         done
27787         for (( i=0; i < $num; i++ )); do
27788                 wait ${pids[$i]}
27789         done
27790         check_lsom_size $DIR/$tfile $size
27791
27792         # multi-client writes
27793         num=$(get_node_count ${CLIENTS//,/ })
27794         size=$(($num * $bs))
27795         offset=0
27796         i=0
27797
27798         echo "Test SOM for multi-client ($num) writes"
27799         $TRUNCATE $DIR/$tfile 0
27800         for client in ${CLIENTS//,/ }; do
27801                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27802                 local pids[$i]=$!
27803                 i=$((i + 1))
27804                 offset=$((offset + $bs))
27805         done
27806         for (( i=0; i < $num; i++ )); do
27807                 wait ${pids[$i]}
27808         done
27809         check_lsom_size $DIR/$tfile $offset
27810
27811         i=0
27812         $TRUNCATE $DIR/$tfile 0
27813         for client in ${CLIENTS//,/ }; do
27814                 offset=$((offset - $bs))
27815                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27816                 local pids[$i]=$!
27817                 i=$((i + 1))
27818         done
27819         for (( i=0; i < $num; i++ )); do
27820                 wait ${pids[$i]}
27821         done
27822         check_lsom_size $DIR/$tfile $size
27823
27824         # verify truncate
27825         echo "Test SOM for truncate"
27826         $TRUNCATE $DIR/$tfile 1048576
27827         check_lsom_size $DIR/$tfile 1048576
27828         $TRUNCATE $DIR/$tfile 1234
27829         check_lsom_size $DIR/$tfile 1234
27830
27831         # verify SOM blocks count
27832         echo "Verify SOM block count"
27833         $TRUNCATE $DIR/$tfile 0
27834         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27835                 error "failed to write file $tfile"
27836         check_lsom_data $DIR/$tfile
27837 }
27838 run_test 806 "Verify Lazy Size on MDS"
27839
27840 test_807() {
27841         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27842         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27843                 skip "Need MDS version at least 2.11.52"
27844
27845         # Registration step
27846         changelog_register || error "changelog_register failed"
27847         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27848         changelog_users $SINGLEMDS | grep -q $cl_user ||
27849                 error "User $cl_user not found in changelog_users"
27850
27851         rm -rf $DIR/$tdir || error "rm $tdir failed"
27852         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27853         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27854         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27855         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27856                 error "truncate $tdir/trunc failed"
27857
27858         local bs=1048576
27859         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27860                 error "write $tfile failed"
27861
27862         # multi-client wirtes
27863         local num=$(get_node_count ${CLIENTS//,/ })
27864         local offset=0
27865         local i=0
27866
27867         echo "Test SOM for multi-client ($num) writes"
27868         touch $DIR/$tfile || error "touch $tfile failed"
27869         $TRUNCATE $DIR/$tfile 0
27870         for client in ${CLIENTS//,/ }; do
27871                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27872                 local pids[$i]=$!
27873                 i=$((i + 1))
27874                 offset=$((offset + $bs))
27875         done
27876         for (( i=0; i < $num; i++ )); do
27877                 wait ${pids[$i]}
27878         done
27879
27880         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27881         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27882         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27883         check_lsom_data $DIR/$tdir/trunc
27884         check_lsom_data $DIR/$tdir/single_dd
27885         check_lsom_data $DIR/$tfile
27886
27887         rm -rf $DIR/$tdir
27888         # Deregistration step
27889         changelog_deregister || error "changelog_deregister failed"
27890 }
27891 run_test 807 "verify LSOM syncing tool"
27892
27893 check_som_nologged()
27894 {
27895         local lines=$($LFS changelog $FSNAME-MDT0000 |
27896                 grep 'x=trusted.som' | wc -l)
27897         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27898 }
27899
27900 test_808() {
27901         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27902                 skip "Need MDS version at least 2.11.55"
27903
27904         # Registration step
27905         changelog_register || error "changelog_register failed"
27906
27907         touch $DIR/$tfile || error "touch $tfile failed"
27908         check_som_nologged
27909
27910         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27911                 error "write $tfile failed"
27912         check_som_nologged
27913
27914         $TRUNCATE $DIR/$tfile 1234
27915         check_som_nologged
27916
27917         $TRUNCATE $DIR/$tfile 1048576
27918         check_som_nologged
27919
27920         # Deregistration step
27921         changelog_deregister || error "changelog_deregister failed"
27922 }
27923 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27924
27925 check_som_nodata()
27926 {
27927         $LFS getsom $1
27928         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27929 }
27930
27931 test_809() {
27932         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27933                 skip "Need MDS version at least 2.11.56"
27934
27935         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27936                 error "failed to create DoM-only file $DIR/$tfile"
27937         touch $DIR/$tfile || error "touch $tfile failed"
27938         check_som_nodata $DIR/$tfile
27939
27940         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27941                 error "write $tfile failed"
27942         check_som_nodata $DIR/$tfile
27943
27944         $TRUNCATE $DIR/$tfile 1234
27945         check_som_nodata $DIR/$tfile
27946
27947         $TRUNCATE $DIR/$tfile 4097
27948         check_som_nodata $DIR/$file
27949 }
27950 run_test 809 "Verify no SOM xattr store for DoM-only files"
27951
27952 test_810() {
27953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27954         $GSS && skip_env "could not run with gss"
27955         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27956                 skip "OST < 2.12.58 doesn't align checksum"
27957
27958         set_checksums 1
27959         stack_trap "set_checksums $ORIG_CSUM" EXIT
27960         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27961
27962         local csum
27963         local before
27964         local after
27965         for csum in $CKSUM_TYPES; do
27966                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27967                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27968                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27969                         eval set -- $i
27970                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27971                         before=$(md5sum $DIR/$tfile)
27972                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27973                         after=$(md5sum $DIR/$tfile)
27974                         [ "$before" == "$after" ] ||
27975                                 error "$csum: $before != $after bs=$1 seek=$2"
27976                 done
27977         done
27978 }
27979 run_test 810 "partial page writes on ZFS (LU-11663)"
27980
27981 test_812a() {
27982         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27983                 skip "OST < 2.12.51 doesn't support this fail_loc"
27984
27985         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27986         # ensure ost1 is connected
27987         stat $DIR/$tfile >/dev/null || error "can't stat"
27988         wait_osc_import_state client ost1 FULL
27989         # no locks, no reqs to let the connection idle
27990         cancel_lru_locks osc
27991
27992         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27993 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27994         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27995         wait_osc_import_state client ost1 CONNECTING
27996         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27997
27998         stat $DIR/$tfile >/dev/null || error "can't stat file"
27999 }
28000 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28001
28002 test_812b() { # LU-12378
28003         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28004                 skip "OST < 2.12.51 doesn't support this fail_loc"
28005
28006         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28007         # ensure ost1 is connected
28008         stat $DIR/$tfile >/dev/null || error "can't stat"
28009         wait_osc_import_state client ost1 FULL
28010         # no locks, no reqs to let the connection idle
28011         cancel_lru_locks osc
28012
28013         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28014 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28015         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28016         wait_osc_import_state client ost1 CONNECTING
28017         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28018
28019         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28020         wait_osc_import_state client ost1 IDLE
28021 }
28022 run_test 812b "do not drop no resend request for idle connect"
28023
28024 test_812c() {
28025         local old
28026
28027         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28028
28029         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28030         $LFS getstripe $DIR/$tfile
28031         $LCTL set_param osc.*.idle_timeout=10
28032         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28033         # ensure ost1 is connected
28034         stat $DIR/$tfile >/dev/null || error "can't stat"
28035         wait_osc_import_state client ost1 FULL
28036         # no locks, no reqs to let the connection idle
28037         cancel_lru_locks osc
28038
28039 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28040         $LCTL set_param fail_loc=0x80000533
28041         sleep 15
28042         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28043 }
28044 run_test 812c "idle import vs lock enqueue race"
28045
28046 test_813() {
28047         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28048         [ -z "$file_heat_sav" ] && skip "no file heat support"
28049
28050         local readsample
28051         local writesample
28052         local readbyte
28053         local writebyte
28054         local readsample1
28055         local writesample1
28056         local readbyte1
28057         local writebyte1
28058
28059         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28060         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28061
28062         $LCTL set_param -n llite.*.file_heat=1
28063         echo "Turn on file heat"
28064         echo "Period second: $period_second, Decay percentage: $decay_pct"
28065
28066         echo "QQQQ" > $DIR/$tfile
28067         echo "QQQQ" > $DIR/$tfile
28068         echo "QQQQ" > $DIR/$tfile
28069         cat $DIR/$tfile > /dev/null
28070         cat $DIR/$tfile > /dev/null
28071         cat $DIR/$tfile > /dev/null
28072         cat $DIR/$tfile > /dev/null
28073
28074         local out=$($LFS heat_get $DIR/$tfile)
28075
28076         $LFS heat_get $DIR/$tfile
28077         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28078         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28079         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28080         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28081
28082         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28083         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28084         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28085         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28086
28087         sleep $((period_second + 3))
28088         echo "Sleep $((period_second + 3)) seconds..."
28089         # The recursion formula to calculate the heat of the file f is as
28090         # follow:
28091         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28092         # Where Hi is the heat value in the period between time points i*I and
28093         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28094         # to the weight of Ci.
28095         out=$($LFS heat_get $DIR/$tfile)
28096         $LFS heat_get $DIR/$tfile
28097         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28098         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28099         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28100         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28101
28102         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28103                 error "read sample ($readsample) is wrong"
28104         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28105                 error "write sample ($writesample) is wrong"
28106         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28107                 error "read bytes ($readbyte) is wrong"
28108         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28109                 error "write bytes ($writebyte) is wrong"
28110
28111         echo "QQQQ" > $DIR/$tfile
28112         echo "QQQQ" > $DIR/$tfile
28113         echo "QQQQ" > $DIR/$tfile
28114         cat $DIR/$tfile > /dev/null
28115         cat $DIR/$tfile > /dev/null
28116         cat $DIR/$tfile > /dev/null
28117         cat $DIR/$tfile > /dev/null
28118
28119         sleep $((period_second + 3))
28120         echo "Sleep $((period_second + 3)) seconds..."
28121
28122         out=$($LFS heat_get $DIR/$tfile)
28123         $LFS heat_get $DIR/$tfile
28124         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28125         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28126         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28127         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28128
28129         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28130                 4 * $decay_pct) / 100") -eq 1 ] ||
28131                 error "read sample ($readsample1) is wrong"
28132         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28133                 3 * $decay_pct) / 100") -eq 1 ] ||
28134                 error "write sample ($writesample1) is wrong"
28135         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28136                 20 * $decay_pct) / 100") -eq 1 ] ||
28137                 error "read bytes ($readbyte1) is wrong"
28138         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28139                 15 * $decay_pct) / 100") -eq 1 ] ||
28140                 error "write bytes ($writebyte1) is wrong"
28141
28142         echo "Turn off file heat for the file $DIR/$tfile"
28143         $LFS heat_set -o $DIR/$tfile
28144
28145         echo "QQQQ" > $DIR/$tfile
28146         echo "QQQQ" > $DIR/$tfile
28147         echo "QQQQ" > $DIR/$tfile
28148         cat $DIR/$tfile > /dev/null
28149         cat $DIR/$tfile > /dev/null
28150         cat $DIR/$tfile > /dev/null
28151         cat $DIR/$tfile > /dev/null
28152
28153         out=$($LFS heat_get $DIR/$tfile)
28154         $LFS heat_get $DIR/$tfile
28155         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28156         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28157         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28158         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28159
28160         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28161         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28162         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28163         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28164
28165         echo "Trun on file heat for the file $DIR/$tfile"
28166         $LFS heat_set -O $DIR/$tfile
28167
28168         echo "QQQQ" > $DIR/$tfile
28169         echo "QQQQ" > $DIR/$tfile
28170         echo "QQQQ" > $DIR/$tfile
28171         cat $DIR/$tfile > /dev/null
28172         cat $DIR/$tfile > /dev/null
28173         cat $DIR/$tfile > /dev/null
28174         cat $DIR/$tfile > /dev/null
28175
28176         out=$($LFS heat_get $DIR/$tfile)
28177         $LFS heat_get $DIR/$tfile
28178         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28179         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28180         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28181         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28182
28183         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28184         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28185         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28186         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28187
28188         $LFS heat_set -c $DIR/$tfile
28189         $LCTL set_param -n llite.*.file_heat=0
28190         echo "Turn off file heat support for the Lustre filesystem"
28191
28192         echo "QQQQ" > $DIR/$tfile
28193         echo "QQQQ" > $DIR/$tfile
28194         echo "QQQQ" > $DIR/$tfile
28195         cat $DIR/$tfile > /dev/null
28196         cat $DIR/$tfile > /dev/null
28197         cat $DIR/$tfile > /dev/null
28198         cat $DIR/$tfile > /dev/null
28199
28200         out=$($LFS heat_get $DIR/$tfile)
28201         $LFS heat_get $DIR/$tfile
28202         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28203         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28204         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28205         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28206
28207         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28208         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28209         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28210         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28211
28212         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28213         rm -f $DIR/$tfile
28214 }
28215 run_test 813 "File heat verfication"
28216
28217 test_814()
28218 {
28219         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28220         echo -n y >> $DIR/$tfile
28221         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28222         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28223 }
28224 run_test 814 "sparse cp works as expected (LU-12361)"
28225
28226 test_815()
28227 {
28228         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28229         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28230 }
28231 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28232
28233 test_816() {
28234         local ost1_imp=$(get_osc_import_name client ost1)
28235         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28236                          cut -d'.' -f2)
28237
28238         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28239         # ensure ost1 is connected
28240
28241         stat $DIR/$tfile >/dev/null || error "can't stat"
28242         wait_osc_import_state client ost1 FULL
28243         # no locks, no reqs to let the connection idle
28244         cancel_lru_locks osc
28245         lru_resize_disable osc
28246         local before
28247         local now
28248         before=$($LCTL get_param -n \
28249                  ldlm.namespaces.$imp_name.lru_size)
28250
28251         wait_osc_import_state client ost1 IDLE
28252         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28253         now=$($LCTL get_param -n \
28254               ldlm.namespaces.$imp_name.lru_size)
28255         [ $before == $now ] || error "lru_size changed $before != $now"
28256 }
28257 run_test 816 "do not reset lru_resize on idle reconnect"
28258
28259 cleanup_817() {
28260         umount $tmpdir
28261         exportfs -u localhost:$DIR/nfsexp
28262         rm -rf $DIR/nfsexp
28263 }
28264
28265 test_817() {
28266         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28267
28268         mkdir -p $DIR/nfsexp
28269         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28270                 error "failed to export nfs"
28271
28272         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28273         stack_trap cleanup_817 EXIT
28274
28275         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28276                 error "failed to mount nfs to $tmpdir"
28277
28278         cp /bin/true $tmpdir
28279         $DIR/nfsexp/true || error "failed to execute 'true' command"
28280 }
28281 run_test 817 "nfsd won't cache write lock for exec file"
28282
28283 test_818() {
28284         test_mkdir -i0 -c1 $DIR/$tdir
28285         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28286         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28287         stop $SINGLEMDS
28288
28289         # restore osp-syn threads
28290         stack_trap "fail $SINGLEMDS"
28291
28292         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28293         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28294         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28295                 error "start $SINGLEMDS failed"
28296         rm -rf $DIR/$tdir
28297
28298         local testid=$(echo $TESTNAME | tr '_' ' ')
28299
28300         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28301                 grep "run LFSCK" || error "run LFSCK is not suggested"
28302 }
28303 run_test 818 "unlink with failed llog"
28304
28305 test_819a() {
28306         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28307         cancel_lru_locks osc
28308         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28309         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28310         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28311         rm -f $TDIR/$tfile
28312 }
28313 run_test 819a "too big niobuf in read"
28314
28315 test_819b() {
28316         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28317         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28318         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28319         cancel_lru_locks osc
28320         sleep 1
28321         rm -f $TDIR/$tfile
28322 }
28323 run_test 819b "too big niobuf in write"
28324
28325
28326 function test_820_start_ost() {
28327         sleep 5
28328
28329         for num in $(seq $OSTCOUNT); do
28330                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28331         done
28332 }
28333
28334 test_820() {
28335         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28336
28337         mkdir $DIR/$tdir
28338         umount_client $MOUNT || error "umount failed"
28339         for num in $(seq $OSTCOUNT); do
28340                 stop ost$num
28341         done
28342
28343         # mount client with no active OSTs
28344         # so that the client can't initialize max LOV EA size
28345         # from OSC notifications
28346         mount_client $MOUNT || error "mount failed"
28347         # delay OST starting to keep this 0 max EA size for a while
28348         test_820_start_ost &
28349
28350         # create a directory on MDS2
28351         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28352                 error "Failed to create directory"
28353         # open intent should update default EA size
28354         # see mdc_update_max_ea_from_body()
28355         # notice this is the very first RPC to MDS2
28356         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28357         ret=$?
28358         echo $out
28359         # With SSK, this situation can lead to -EPERM being returned.
28360         # In that case, simply retry.
28361         if [ $ret -ne 0 ] && $SHARED_KEY; then
28362                 if echo "$out" | grep -q "not permitted"; then
28363                         cp /etc/services $DIR/$tdir/mds2
28364                         ret=$?
28365                 fi
28366         fi
28367         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28368 }
28369 run_test 820 "update max EA from open intent"
28370
28371 test_822() {
28372         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28373
28374         save_lustre_params mds1 \
28375                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28376         do_facet $SINGLEMDS "$LCTL set_param -n \
28377                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28378         do_facet $SINGLEMDS "$LCTL set_param -n \
28379                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28380
28381         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28382         local maxage=$(do_facet mds1 $LCTL get_param -n \
28383                        osp.$FSNAME-OST0000*MDT0000.maxage)
28384         sleep $((maxage + 1))
28385
28386         #define OBD_FAIL_NET_ERROR_RPC          0x532
28387         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28388
28389         stack_trap "restore_lustre_params < $p; rm $p"
28390
28391         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28392                       osp.$FSNAME-OST0000*MDT0000.create_count")
28393         for i in $(seq 1 $count); do
28394                 touch $DIR/$tfile.${i} || error "touch failed"
28395         done
28396 }
28397 run_test 822 "test precreate failure"
28398
28399 test_823() {
28400         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28401         local OST_MAX_PRECREATE=20000
28402
28403         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28404                 skip "Need MDS version at least 2.14.56"
28405
28406         save_lustre_params mds1 \
28407                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28408         do_facet $SINGLEMDS "$LCTL set_param -n \
28409                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28410         do_facet $SINGLEMDS "$LCTL set_param -n \
28411                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28412
28413         stack_trap "restore_lustre_params < $p; rm $p"
28414
28415         do_facet $SINGLEMDS "$LCTL set_param -n \
28416                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28417
28418         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28419                       osp.$FSNAME-OST0000*MDT0000.create_count")
28420         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28421                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28422         local expect_count=$(((($max/2)/256) * 256))
28423
28424         log "setting create_count to 100200:"
28425         log " -result- count: $count with max: $max, expecting: $expect_count"
28426
28427         [[ $count -eq expect_count ]] ||
28428                 error "Create count not set to max precreate."
28429 }
28430 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28431
28432 test_831() {
28433         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28434                 skip "Need MDS version 2.14.56"
28435
28436         local sync_changes=$(do_facet $SINGLEMDS \
28437                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28438
28439         [ "$sync_changes" -gt 100 ] &&
28440                 skip "Sync changes $sync_changes > 100 already"
28441
28442         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28443
28444         $LFS mkdir -i 0 $DIR/$tdir
28445         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28446
28447         save_lustre_params mds1 \
28448                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28449         save_lustre_params mds1 \
28450                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28451
28452         do_facet mds1 "$LCTL set_param -n \
28453                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28454                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28455         stack_trap "restore_lustre_params < $p" EXIT
28456
28457         createmany -o $DIR/$tdir/f- 1000
28458         unlinkmany $DIR/$tdir/f- 1000 &
28459         local UNLINK_PID=$!
28460
28461         while sleep 1; do
28462                 sync_changes=$(do_facet mds1 \
28463                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28464                 # the check in the code is racy, fail the test
28465                 # if the value above the limit by 10.
28466                 [ $sync_changes -gt 110 ] && {
28467                         kill -2 $UNLINK_PID
28468                         wait
28469                         error "osp changes throttling failed, $sync_changes>110"
28470                 }
28471                 kill -0 $UNLINK_PID 2> /dev/null || break
28472         done
28473         wait
28474 }
28475 run_test 831 "throttling unlink/setattr queuing on OSP"
28476
28477 #
28478 # tests that do cleanup/setup should be run at the end
28479 #
28480
28481 test_900() {
28482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28483         local ls
28484
28485         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28486         $LCTL set_param fail_loc=0x903
28487
28488         cancel_lru_locks MGC
28489
28490         FAIL_ON_ERROR=true cleanup
28491         FAIL_ON_ERROR=true setup
28492 }
28493 run_test 900 "umount should not race with any mgc requeue thread"
28494
28495 # LUS-6253/LU-11185
28496 test_901() {
28497         local old
28498         local count
28499         local oldc
28500         local newc
28501         local olds
28502         local news
28503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28504
28505         # some get_param have a bug to handle dot in param name
28506         cancel_lru_locks MGC
28507         old=$(mount -t lustre | wc -l)
28508         # 1 config+sptlrpc
28509         # 2 params
28510         # 3 nodemap
28511         # 4 IR
28512         old=$((old * 4))
28513         oldc=0
28514         count=0
28515         while [ $old -ne $oldc ]; do
28516                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28517                 sleep 1
28518                 ((count++))
28519                 if [ $count -ge $TIMEOUT ]; then
28520                         error "too large timeout"
28521                 fi
28522         done
28523         umount_client $MOUNT || error "umount failed"
28524         mount_client $MOUNT || error "mount failed"
28525         cancel_lru_locks MGC
28526         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28527
28528         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28529
28530         return 0
28531 }
28532 run_test 901 "don't leak a mgc lock on client umount"
28533
28534 # LU-13377
28535 test_902() {
28536         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28537                 skip "client does not have LU-13377 fix"
28538         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28539         $LCTL set_param fail_loc=0x1415
28540         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28541         cancel_lru_locks osc
28542         rm -f $DIR/$tfile
28543 }
28544 run_test 902 "test short write doesn't hang lustre"
28545
28546 # LU-14711
28547 test_903() {
28548         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28549         echo "blah" > $DIR/${tfile}-2
28550         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28551         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28552         $LCTL set_param fail_loc=0x417 fail_val=20
28553
28554         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28555         sleep 1 # To start the destroy
28556         wait_destroy_complete 150 || error "Destroy taking too long"
28557         cat $DIR/$tfile > /dev/null || error "Evicted"
28558 }
28559 run_test 903 "Test long page discard does not cause evictions"
28560
28561 test_904() {
28562         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28563         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28564                 grep -q project || skip "skip project quota not supported"
28565
28566         local testfile="$DIR/$tdir/$tfile"
28567         local xattr="trusted.projid"
28568         local projid
28569         local mdts=$(comma_list $(mdts_nodes))
28570         local saved=$(do_facet mds1 $LCTL get_param -n \
28571                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28572
28573         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28574         stack_trap "do_nodes $mdts $LCTL set_param \
28575                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28576
28577         mkdir -p $DIR/$tdir
28578         touch $testfile
28579         #hide projid xattr on server
28580         $LFS project -p 1 $testfile ||
28581                 error "set $testfile project id failed"
28582         getfattr -m - $testfile | grep $xattr &&
28583                 error "do not show trusted.projid when disabled on server"
28584         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28585         #should be hidden when projid is 0
28586         $LFS project -p 0 $testfile ||
28587                 error "set $testfile project id failed"
28588         getfattr -m - $testfile | grep $xattr &&
28589                 error "do not show trusted.projid with project ID 0"
28590
28591         #still can getxattr explicitly
28592         projid=$(getfattr -n $xattr $testfile |
28593                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28594         [ $projid == "0" ] ||
28595                 error "projid expected 0 not $projid"
28596
28597         #set the projid via setxattr
28598         setfattr -n $xattr -v "1000" $testfile ||
28599                 error "setattr failed with $?"
28600         projid=($($LFS project $testfile))
28601         [ ${projid[0]} == "1000" ] ||
28602                 error "projid expected 1000 not $projid"
28603
28604         #check the new projid via getxattr
28605         $LFS project -p 1001 $testfile ||
28606                 error "set $testfile project id failed"
28607         getfattr -m - $testfile | grep $xattr ||
28608                 error "should show trusted.projid when project ID != 0"
28609         projid=$(getfattr -n $xattr $testfile |
28610                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28611         [ $projid == "1001" ] ||
28612                 error "projid expected 1001 not $projid"
28613
28614         #try to set invalid projid
28615         setfattr -n $xattr -v "4294967295" $testfile &&
28616                 error "set invalid projid should fail"
28617
28618         #remove the xattr means setting projid to 0
28619         setfattr -x $xattr $testfile ||
28620                 error "setfattr failed with $?"
28621         projid=($($LFS project $testfile))
28622         [ ${projid[0]} == "0" ] ||
28623                 error "projid expected 0 not $projid"
28624
28625         #should be hidden when parent has inherit flag and same projid
28626         $LFS project -srp 1002 $DIR/$tdir ||
28627                 error "set $tdir project id failed"
28628         getfattr -m - $testfile | grep $xattr &&
28629                 error "do not show trusted.projid with inherit flag"
28630
28631         #still can getxattr explicitly
28632         projid=$(getfattr -n $xattr $testfile |
28633                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28634         [ $projid == "1002" ] ||
28635                 error "projid expected 1002 not $projid"
28636 }
28637 run_test 904 "virtual project ID xattr"
28638
28639 # LU-8582
28640 test_905() {
28641         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28642                 skip "lustre < 2.8.54 does not support ladvise"
28643
28644         remote_ost_nodsh && skip "remote OST with nodsh"
28645         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28646
28647         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28648
28649         #define OBD_FAIL_OST_OPCODE 0x253
28650         # OST_LADVISE = 21
28651         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28652         $LFS ladvise -a willread $DIR/$tfile &&
28653                 error "unexpected success of ladvise with fault injection"
28654         $LFS ladvise -a willread $DIR/$tfile |&
28655                 grep -q "Operation not supported"
28656         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28657 }
28658 run_test 905 "bad or new opcode should not stuck client"
28659
28660 complete $SECONDS
28661 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28662 check_and_cleanup_lustre
28663 if [ "$I_MOUNTED" != "yes" ]; then
28664         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28665 fi
28666 exit_status