Whamcloud - gitweb
LU-15653 client: able to cleanup devices manually
[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         always_except LU-15910 413g
50 fi
51
52 # skip the grant tests for ARM until they are fixed
53 if [[ $(uname -m) = aarch64 ]]; then
54         always_except LU-11671 45
55 fi
56
57 # skip nfs tests on kernels >= 4.12.0 until they are fixed
58 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
59         always_except LU-12661 817
60 fi
61 # skip cgroup tests on RHEL8.1 kernels until they are fixed
62 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
63       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
64         always_except LU-13063 411
65 fi
66
67 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
68 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
69         always_except LU-15259 103a 125 154a
70 fi
71
72 #                                  5              12     8   12  15   (min)"
73 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
74
75 if [ "$mds1_FSTYPE" = "zfs" ]; then
76         #                                               13    (min)"
77         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
78 fi
79
80 if [ "$ost1_FSTYPE" = "zfs" ]; then
81         always_except LU-1941 130a 130b 130c 130d 130e 130f 130g
82 fi
83
84 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 always_except LU-4341 170
105
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 always_except LU-3703 234
108 elif [ -r /etc/os-release ]; then
109         if grep -qi ubuntu /etc/os-release; then
110                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
111                                                 -e 's/^VERSION=//p' \
112                                                 /etc/os-release |
113                                                 awk '{ print $1 }'))
114
115                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
116                         always_except LU-10334 103a
117                         always_except LU-10366 410
118                 fi
119         fi
120 fi
121
122 build_test_filter
123 FAIL_ON_ERROR=false
124
125 cleanup() {
126         echo -n "cln.."
127         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
128         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
129 }
130 setup() {
131         echo -n "mnt.."
132         load_modules
133         setupall || exit 10
134         echo "done"
135 }
136
137 check_swap_layouts_support()
138 {
139         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
140                 skip "Does not support layout lock."
141 }
142
143 check_swap_layout_no_dom()
144 {
145         local FOLDER=$1
146         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
147         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
148 }
149
150 check_and_setup_lustre
151 DIR=${DIR:-$MOUNT}
152 assert_DIR
153
154 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
155
156 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
157 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
158 rm -rf $DIR/[Rdfs][0-9]*
159
160 # $RUNAS_ID may get set incorrectly somewhere else
161 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
162         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
163
164 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
165
166 if [ "${ONLY}" = "MOUNT" ] ; then
167         echo "Lustre is up, please go on"
168         exit
169 fi
170
171 echo "preparing for tests involving mounts"
172 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
173 touch $EXT2_DEV
174 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
175 echo # add a newline after mke2fs.
176
177 umask 077
178
179 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
180 lctl set_param debug=-1 2> /dev/null || true
181 test_0a() {
182         touch $DIR/$tfile
183         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
184         rm $DIR/$tfile
185         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
186 }
187 run_test 0a "touch; rm ====================="
188
189 test_0b() {
190         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
191         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
192 }
193 run_test 0b "chmod 0755 $DIR ============================="
194
195 test_0c() {
196         $LCTL get_param mdc.*.import | grep "state: FULL" ||
197                 error "import not FULL"
198         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
199                 error "bad target"
200 }
201 run_test 0c "check import proc"
202
203 test_0d() { # LU-3397
204         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
205                 skip "proc exports not supported before 2.10.57"
206
207         local mgs_exp="mgs.MGS.exports"
208         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
209         local exp_client_nid
210         local exp_client_version
211         local exp_val
212         local imp_val
213         local temp_imp=$DIR/$tfile.import
214         local temp_exp=$DIR/$tfile.export
215
216         # save mgc import file to $temp_imp
217         $LCTL get_param mgc.*.import | tee $temp_imp
218         # Check if client uuid is found in MGS export
219         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
220                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
221                         $client_uuid ] &&
222                         break;
223         done
224         # save mgs export file to $temp_exp
225         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
226
227         # Compare the value of field "connect_flags"
228         imp_val=$(grep "connect_flags" $temp_imp)
229         exp_val=$(grep "connect_flags" $temp_exp)
230         [ "$exp_val" == "$imp_val" ] ||
231                 error "export flags '$exp_val' != import flags '$imp_val'"
232
233         # Compare client versions.  Only compare top-3 fields for compatibility
234         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
235         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
236         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
237         [ "$exp_val" == "$imp_val" ] ||
238                 error "exp version '$exp_client_version'($exp_val) != " \
239                         "'$(lustre_build_version client)'($imp_val)"
240 }
241 run_test 0d "check export proc ============================="
242
243 test_0e() { # LU-13417
244         (( $MDSCOUNT > 1 )) ||
245                 skip "We need at least 2 MDTs for this test"
246
247         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
248                 skip "Need server version at least 2.14.51"
249
250         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
251         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
252
253         [ $default_lmv_count -eq 1 ] ||
254                 error "$MOUNT default stripe count $default_lmv_count"
255
256         [ $default_lmv_index -eq -1 ] ||
257                 error "$MOUNT default stripe index $default_lmv_index"
258
259         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
260         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
261
262         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
263         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
264
265         [ $mdt_index1 -eq $mdt_index2 ] &&
266                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
267
268         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
269 }
270 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
271
272 test_1() {
273         test_mkdir $DIR/$tdir
274         test_mkdir $DIR/$tdir/d2
275         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
276         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
277         rmdir $DIR/$tdir/d2
278         rmdir $DIR/$tdir
279         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
280 }
281 run_test 1 "mkdir; remkdir; rmdir"
282
283 test_2() {
284         test_mkdir $DIR/$tdir
285         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
286         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
287         rm -r $DIR/$tdir
288         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
289 }
290 run_test 2 "mkdir; touch; rmdir; check file"
291
292 test_3() {
293         test_mkdir $DIR/$tdir
294         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
295         touch $DIR/$tdir/$tfile
296         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
297         rm -r $DIR/$tdir
298         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
299 }
300 run_test 3 "mkdir; touch; rmdir; check dir"
301
302 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
303 test_4() {
304         test_mkdir -i 1 $DIR/$tdir
305
306         touch $DIR/$tdir/$tfile ||
307                 error "Create file under remote directory failed"
308
309         rmdir $DIR/$tdir &&
310                 error "Expect error removing in-use dir $DIR/$tdir"
311
312         test -d $DIR/$tdir || error "Remote directory disappeared"
313
314         rm -rf $DIR/$tdir || error "remove remote dir error"
315 }
316 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
317
318 test_5() {
319         test_mkdir $DIR/$tdir
320         test_mkdir $DIR/$tdir/d2
321         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
322         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
323         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
324 }
325 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
326
327 test_6a() {
328         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
329         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
330         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
331                 error "$tfile does not have perm 0666 or UID $UID"
332         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
333         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
334                 error "$tfile should be 0666 and owned by UID $UID"
335 }
336 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
337
338 test_6c() {
339         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
340
341         touch $DIR/$tfile
342         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
343         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
344                 error "$tfile should be owned by UID $RUNAS_ID"
345         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
346         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
347                 error "$tfile should be owned by UID $RUNAS_ID"
348 }
349 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
350
351 test_6e() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by GID $UID"
358         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
361 }
362 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
363
364 test_6g() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         test_mkdir $DIR/$tdir
368         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
369         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
370         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
371         test_mkdir $DIR/$tdir/d/subdir
372         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
373                 error "$tdir/d/subdir should be GID $RUNAS_GID"
374         if [[ $MDSCOUNT -gt 1 ]]; then
375                 # check remote dir sgid inherite
376                 $LFS mkdir -i 0 $DIR/$tdir.local ||
377                         error "mkdir $tdir.local failed"
378                 chmod g+s $DIR/$tdir.local ||
379                         error "chmod $tdir.local failed"
380                 chgrp $RUNAS_GID $DIR/$tdir.local ||
381                         error "chgrp $tdir.local failed"
382                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
383                         error "mkdir $tdir.remote failed"
384                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
385                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
386                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
387                         error "$tdir.remote should be mode 02755"
388         fi
389 }
390 run_test 6g "verify new dir in sgid dir inherits group"
391
392 test_6h() { # bug 7331
393         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
394
395         touch $DIR/$tfile || error "touch failed"
396         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
397         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
398                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
399         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
400                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
401 }
402 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
403
404 test_7a() {
405         test_mkdir $DIR/$tdir
406         $MCREATE $DIR/$tdir/$tfile
407         chmod 0666 $DIR/$tdir/$tfile
408         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
409                 error "$tdir/$tfile should be mode 0666"
410 }
411 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
412
413 test_7b() {
414         if [ ! -d $DIR/$tdir ]; then
415                 test_mkdir $DIR/$tdir
416         fi
417         $MCREATE $DIR/$tdir/$tfile
418         echo -n foo > $DIR/$tdir/$tfile
419         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
420         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
421 }
422 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
423
424 test_8() {
425         test_mkdir $DIR/$tdir
426         touch $DIR/$tdir/$tfile
427         chmod 0666 $DIR/$tdir/$tfile
428         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
429                 error "$tfile mode not 0666"
430 }
431 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
432
433 test_9() {
434         test_mkdir $DIR/$tdir
435         test_mkdir $DIR/$tdir/d2
436         test_mkdir $DIR/$tdir/d2/d3
437         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
438 }
439 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
440
441 test_10() {
442         test_mkdir $DIR/$tdir
443         test_mkdir $DIR/$tdir/d2
444         touch $DIR/$tdir/d2/$tfile
445         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
446                 error "$tdir/d2/$tfile not a file"
447 }
448 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
449
450 test_11() {
451         test_mkdir $DIR/$tdir
452         test_mkdir $DIR/$tdir/d2
453         chmod 0666 $DIR/$tdir/d2
454         chmod 0705 $DIR/$tdir/d2
455         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
456                 error "$tdir/d2 mode not 0705"
457 }
458 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
459
460 test_12() {
461         test_mkdir $DIR/$tdir
462         touch $DIR/$tdir/$tfile
463         chmod 0666 $DIR/$tdir/$tfile
464         chmod 0654 $DIR/$tdir/$tfile
465         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
466                 error "$tdir/d2 mode not 0654"
467 }
468 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
469
470 test_13() {
471         test_mkdir $DIR/$tdir
472         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
473         >  $DIR/$tdir/$tfile
474         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
475                 error "$tdir/$tfile size not 0 after truncate"
476 }
477 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
478
479 test_14() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
486
487 test_15() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
491         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
492                 error "$tdir/${tfile_2} not a file after rename"
493         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
494 }
495 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
496
497 test_16() {
498         test_mkdir $DIR/$tdir
499         touch $DIR/$tdir/$tfile
500         rm -rf $DIR/$tdir/$tfile
501         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
502 }
503 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
504
505 test_17a() {
506         test_mkdir $DIR/$tdir
507         touch $DIR/$tdir/$tfile
508         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
509         ls -l $DIR/$tdir
510         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
511                 error "$tdir/l-exist not a symlink"
512         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
513                 error "$tdir/l-exist not referencing a file"
514         rm -f $DIR/$tdir/l-exist
515         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
516 }
517 run_test 17a "symlinks: create, remove (real)"
518
519 test_17b() {
520         test_mkdir $DIR/$tdir
521         ln -s no-such-file $DIR/$tdir/l-dangle
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
524                 error "$tdir/l-dangle not referencing no-such-file"
525         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
526                 error "$tdir/l-dangle not referencing non-existent file"
527         rm -f $DIR/$tdir/l-dangle
528         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
529 }
530 run_test 17b "symlinks: create, remove (dangling)"
531
532 test_17c() { # bug 3440 - don't save failed open RPC for replay
533         test_mkdir $DIR/$tdir
534         ln -s foo $DIR/$tdir/$tfile
535         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
536 }
537 run_test 17c "symlinks: open dangling (should return error)"
538
539 test_17d() {
540         test_mkdir $DIR/$tdir
541         ln -s foo $DIR/$tdir/$tfile
542         touch $DIR/$tdir/$tfile || error "creating to new symlink"
543 }
544 run_test 17d "symlinks: create dangling"
545
546 test_17e() {
547         test_mkdir $DIR/$tdir
548         local foo=$DIR/$tdir/$tfile
549         ln -s $foo $foo || error "create symlink failed"
550         ls -l $foo || error "ls -l failed"
551         ls $foo && error "ls not failed" || true
552 }
553 run_test 17e "symlinks: create recursive symlink (should return error)"
554
555 test_17f() {
556         test_mkdir $DIR/$tdir
557         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
562         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
563         ls -l  $DIR/$tdir
564 }
565 run_test 17f "symlinks: long and very long symlink name"
566
567 # str_repeat(S, N) generate a string that is string S repeated N times
568 str_repeat() {
569         local s=$1
570         local n=$2
571         local ret=''
572         while [ $((n -= 1)) -ge 0 ]; do
573                 ret=$ret$s
574         done
575         echo $ret
576 }
577
578 # Long symlinks and LU-2241
579 test_17g() {
580         test_mkdir $DIR/$tdir
581         local TESTS="59 60 61 4094 4095"
582
583         # Fix for inode size boundary in 2.1.4
584         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
585                 TESTS="4094 4095"
586
587         # Patch not applied to 2.2 or 2.3 branches
588         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
589         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
590                 TESTS="4094 4095"
591
592         for i in $TESTS; do
593                 local SYMNAME=$(str_repeat 'x' $i)
594                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
595                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
596         done
597 }
598 run_test 17g "symlinks: really long symlink name and inode boundaries"
599
600 test_17h() { #bug 17378
601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
602         remote_mds_nodsh && skip "remote MDS with nodsh"
603
604         local mdt_idx
605
606         test_mkdir $DIR/$tdir
607         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
608         $LFS setstripe -c -1 $DIR/$tdir
609         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
610         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
611         touch $DIR/$tdir/$tfile || true
612 }
613 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
614
615 test_17i() { #bug 20018
616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
617         remote_mds_nodsh && skip "remote MDS with nodsh"
618
619         local foo=$DIR/$tdir/$tfile
620         local mdt_idx
621
622         test_mkdir -c1 $DIR/$tdir
623         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
624         ln -s $foo $foo || error "create symlink failed"
625 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
626         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
627         ls -l $foo && error "error not detected"
628         return 0
629 }
630 run_test 17i "don't panic on short symlink (should return error)"
631
632 test_17k() { #bug 22301
633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
634         [[ -z "$(which rsync 2>/dev/null)" ]] &&
635                 skip "no rsync command"
636         rsync --help | grep -q xattr ||
637                 skip_env "$(rsync --version | head -n1) does not support xattrs"
638         test_mkdir $DIR/$tdir
639         test_mkdir $DIR/$tdir.new
640         touch $DIR/$tdir/$tfile
641         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
642         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
643                 error "rsync failed with xattrs enabled"
644 }
645 run_test 17k "symlinks: rsync with xattrs enabled"
646
647 test_17l() { # LU-279
648         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
649                 skip "no getfattr command"
650
651         test_mkdir $DIR/$tdir
652         touch $DIR/$tdir/$tfile
653         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
654         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
655                 # -h to not follow symlinks. -m '' to list all the xattrs.
656                 # grep to remove first line: '# file: $path'.
657                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
658                 do
659                         lgetxattr_size_check $path $xattr ||
660                                 error "lgetxattr_size_check $path $xattr failed"
661                 done
662         done
663 }
664 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
665
666 # LU-1540
667 test_17m() {
668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
669         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
670         remote_mds_nodsh && skip "remote MDS with nodsh"
671         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
672         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
673                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
674
675         local short_sym="0123456789"
676         local wdir=$DIR/$tdir
677         local i
678
679         test_mkdir $wdir
680         long_sym=$short_sym
681         # create a long symlink file
682         for ((i = 0; i < 4; ++i)); do
683                 long_sym=${long_sym}${long_sym}
684         done
685
686         echo "create 512 short and long symlink files under $wdir"
687         for ((i = 0; i < 256; ++i)); do
688                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
689                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
690         done
691
692         echo "erase them"
693         rm -f $wdir/*
694         sync
695         wait_delete_completed
696
697         echo "recreate the 512 symlink files with a shorter string"
698         for ((i = 0; i < 512; ++i)); do
699                 # rewrite the symlink file with a shorter string
700                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
701                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
702         done
703
704         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
705
706         echo "stop and checking mds${mds_index}:"
707         # e2fsck should not return error
708         stop mds${mds_index}
709         local devname=$(mdsdevname $mds_index)
710         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
711         rc=$?
712
713         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
714                 error "start mds${mds_index} failed"
715         df $MOUNT > /dev/null 2>&1
716         [ $rc -eq 0 ] ||
717                 error "e2fsck detected error for short/long symlink: rc=$rc"
718         rm -f $wdir/*
719 }
720 run_test 17m "run e2fsck against MDT which contains short/long symlink"
721
722 check_fs_consistency_17n() {
723         local mdt_index
724         local rc=0
725
726         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
727         # so it only check MDT1/MDT2 instead of all of MDTs.
728         for mdt_index in 1 2; do
729                 # e2fsck should not return error
730                 stop mds${mdt_index}
731                 local devname=$(mdsdevname $mdt_index)
732                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
733                         rc=$((rc + $?))
734
735                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
736                         error "mount mds$mdt_index failed"
737                 df $MOUNT > /dev/null 2>&1
738         done
739         return $rc
740 }
741
742 test_17n() {
743         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
745         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
746         remote_mds_nodsh && skip "remote MDS with nodsh"
747         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
748         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
749                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
750
751         local i
752
753         test_mkdir $DIR/$tdir
754         for ((i=0; i<10; i++)); do
755                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
756                         error "create remote dir error $i"
757                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
758                         error "create files under remote dir failed $i"
759         done
760
761         check_fs_consistency_17n ||
762                 error "e2fsck report error after create files under remote dir"
763
764         for ((i = 0; i < 10; i++)); do
765                 rm -rf $DIR/$tdir/remote_dir_${i} ||
766                         error "destroy remote dir error $i"
767         done
768
769         check_fs_consistency_17n ||
770                 error "e2fsck report error after unlink files under remote dir"
771
772         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
773                 skip "lustre < 2.4.50 does not support migrate mv"
774
775         for ((i = 0; i < 10; i++)); do
776                 mkdir -p $DIR/$tdir/remote_dir_${i}
777                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
778                         error "create files under remote dir failed $i"
779                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
780                         error "migrate remote dir error $i"
781         done
782         check_fs_consistency_17n || error "e2fsck report error after migration"
783
784         for ((i = 0; i < 10; i++)); do
785                 rm -rf $DIR/$tdir/remote_dir_${i} ||
786                         error "destroy remote dir error $i"
787         done
788
789         check_fs_consistency_17n || error "e2fsck report error after unlink"
790 }
791 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
792
793 test_17o() {
794         remote_mds_nodsh && skip "remote MDS with nodsh"
795         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
796                 skip "Need MDS version at least 2.3.64"
797
798         local wdir=$DIR/${tdir}o
799         local mdt_index
800         local rc=0
801
802         test_mkdir $wdir
803         touch $wdir/$tfile
804         mdt_index=$($LFS getstripe -m $wdir/$tfile)
805         mdt_index=$((mdt_index + 1))
806
807         cancel_lru_locks mdc
808         #fail mds will wait the failover finish then set
809         #following fail_loc to avoid interfer the recovery process.
810         fail mds${mdt_index}
811
812         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
813         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
814         ls -l $wdir/$tfile && rc=1
815         do_facet mds${mdt_index} lctl set_param fail_loc=0
816         [[ $rc -eq 0 ]] || error "stat file should fail"
817 }
818 run_test 17o "stat file with incompat LMA feature"
819
820 test_18() {
821         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
822         ls $DIR || error "Failed to ls $DIR: $?"
823 }
824 run_test 18 "touch .../f ; ls ... =============================="
825
826 test_19a() {
827         touch $DIR/$tfile
828         ls -l $DIR
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
833
834 test_19b() {
835         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
836 }
837 run_test 19b "ls -l .../f19 (should return error) =============="
838
839 test_19c() {
840         [ $RUNAS_ID -eq $UID ] &&
841                 skip_env "RUNAS_ID = UID = $UID -- skipping"
842
843         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
844 }
845 run_test 19c "$RUNAS touch .../f19 (should return error) =="
846
847 test_19d() {
848         cat $DIR/f19 && error || true
849 }
850 run_test 19d "cat .../f19 (should return error) =============="
851
852 test_20() {
853         touch $DIR/$tfile
854         rm $DIR/$tfile
855         touch $DIR/$tfile
856         rm $DIR/$tfile
857         touch $DIR/$tfile
858         rm $DIR/$tfile
859         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
860 }
861 run_test 20 "touch .../f ; ls -l ..."
862
863 test_21() {
864         test_mkdir $DIR/$tdir
865         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
866         ln -s dangle $DIR/$tdir/link
867         echo foo >> $DIR/$tdir/link
868         cat $DIR/$tdir/dangle
869         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
870         $CHECKSTAT -f -t file $DIR/$tdir/link ||
871                 error "$tdir/link not linked to a file"
872 }
873 run_test 21 "write to dangling link"
874
875 test_22() {
876         local wdir=$DIR/$tdir
877         test_mkdir $wdir
878         chown $RUNAS_ID:$RUNAS_GID $wdir
879         (cd $wdir || error "cd $wdir failed";
880                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
881                 $RUNAS tar xf -)
882         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
883         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
884         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
885                 error "checkstat -u failed"
886 }
887 run_test 22 "unpack tar archive as non-root user"
888
889 # was test_23
890 test_23a() {
891         test_mkdir $DIR/$tdir
892         local file=$DIR/$tdir/$tfile
893
894         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
895         openfile -f O_CREAT:O_EXCL $file &&
896                 error "$file recreate succeeded" || true
897 }
898 run_test 23a "O_CREAT|O_EXCL in subdir"
899
900 test_23b() { # bug 18988
901         test_mkdir $DIR/$tdir
902         local file=$DIR/$tdir/$tfile
903
904         rm -f $file
905         echo foo > $file || error "write filed"
906         echo bar >> $file || error "append filed"
907         $CHECKSTAT -s 8 $file || error "wrong size"
908         rm $file
909 }
910 run_test 23b "O_APPEND check"
911
912 # LU-9409, size with O_APPEND and tiny writes
913 test_23c() {
914         local file=$DIR/$tfile
915
916         # single dd
917         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
918         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
919         rm -f $file
920
921         # racing tiny writes
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
924         wait
925         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
926         rm -f $file
927
928         #racing tiny & normal writes
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
931         wait
932         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
933         rm -f $file
934
935         #racing tiny & normal writes 2, ugly numbers
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
937         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
938         wait
939         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
940         rm -f $file
941 }
942 run_test 23c "O_APPEND size checks for tiny writes"
943
944 # LU-11069 file offset is correct after appending writes
945 test_23d() {
946         local file=$DIR/$tfile
947         local offset
948
949         echo CentaurHauls > $file
950         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
951         if ((offset != 26)); then
952                 error "wrong offset, expected 26, got '$offset'"
953         fi
954 }
955 run_test 23d "file offset is correct after appending writes"
956
957 # rename sanity
958 test_24a() {
959         echo '-- same directory rename'
960         test_mkdir $DIR/$tdir
961         touch $DIR/$tdir/$tfile.1
962         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
963         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
964 }
965 run_test 24a "rename file to non-existent target"
966
967 test_24b() {
968         test_mkdir $DIR/$tdir
969         touch $DIR/$tdir/$tfile.{1,2}
970         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
971         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
972         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
973 }
974 run_test 24b "rename file to existing target"
975
976 test_24c() {
977         test_mkdir $DIR/$tdir
978         test_mkdir $DIR/$tdir/d$testnum.1
979         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
980         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
981         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
982 }
983 run_test 24c "rename directory to non-existent target"
984
985 test_24d() {
986         test_mkdir -c1 $DIR/$tdir
987         test_mkdir -c1 $DIR/$tdir/d$testnum.1
988         test_mkdir -c1 $DIR/$tdir/d$testnum.2
989         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
990         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
991         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
992 }
993 run_test 24d "rename directory to existing target"
994
995 test_24e() {
996         echo '-- cross directory renames --'
997         test_mkdir $DIR/R5a
998         test_mkdir $DIR/R5b
999         touch $DIR/R5a/f
1000         mv $DIR/R5a/f $DIR/R5b/g
1001         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1002         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1003 }
1004 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1005
1006 test_24f() {
1007         test_mkdir $DIR/R6a
1008         test_mkdir $DIR/R6b
1009         touch $DIR/R6a/f $DIR/R6b/g
1010         mv $DIR/R6a/f $DIR/R6b/g
1011         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1012         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1013 }
1014 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1015
1016 test_24g() {
1017         test_mkdir $DIR/R7a
1018         test_mkdir $DIR/R7b
1019         test_mkdir $DIR/R7a/d
1020         mv $DIR/R7a/d $DIR/R7b/e
1021         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1022         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1023 }
1024 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1025
1026 test_24h() {
1027         test_mkdir -c1 $DIR/R8a
1028         test_mkdir -c1 $DIR/R8b
1029         test_mkdir -c1 $DIR/R8a/d
1030         test_mkdir -c1 $DIR/R8b/e
1031         mrename $DIR/R8a/d $DIR/R8b/e
1032         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1033         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1034 }
1035 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1036
1037 test_24i() {
1038         echo "-- rename error cases"
1039         test_mkdir $DIR/R9
1040         test_mkdir $DIR/R9/a
1041         touch $DIR/R9/f
1042         mrename $DIR/R9/f $DIR/R9/a
1043         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1044         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1045         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1046 }
1047 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1048
1049 test_24j() {
1050         test_mkdir $DIR/R10
1051         mrename $DIR/R10/f $DIR/R10/g
1052         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1053         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1054         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1055 }
1056 run_test 24j "source does not exist ============================"
1057
1058 test_24k() {
1059         test_mkdir $DIR/R11a
1060         test_mkdir $DIR/R11a/d
1061         touch $DIR/R11a/f
1062         mv $DIR/R11a/f $DIR/R11a/d
1063         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1064         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1065 }
1066 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1067
1068 # bug 2429 - rename foo foo foo creates invalid file
1069 test_24l() {
1070         f="$DIR/f24l"
1071         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1072 }
1073 run_test 24l "Renaming a file to itself ========================"
1074
1075 test_24m() {
1076         f="$DIR/f24m"
1077         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1078         # on ext3 this does not remove either the source or target files
1079         # though the "expected" operation would be to remove the source
1080         $CHECKSTAT -t file ${f} || error "${f} missing"
1081         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1082 }
1083 run_test 24m "Renaming a file to a hard link to itself ========="
1084
1085 test_24n() {
1086     f="$DIR/f24n"
1087     # this stats the old file after it was renamed, so it should fail
1088     touch ${f}
1089     $CHECKSTAT ${f} || error "${f} missing"
1090     mv ${f} ${f}.rename
1091     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1092     $CHECKSTAT -a ${f} || error "${f} exists"
1093 }
1094 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1095
1096 test_24o() {
1097         test_mkdir $DIR/$tdir
1098         rename_many -s random -v -n 10 $DIR/$tdir
1099 }
1100 run_test 24o "rename of files during htree split"
1101
1102 test_24p() {
1103         test_mkdir $DIR/R12a
1104         test_mkdir $DIR/R12b
1105         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1106         mrename $DIR/R12a $DIR/R12b
1107         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1108         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1109         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1110         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1111 }
1112 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1113
1114 cleanup_multiop_pause() {
1115         trap 0
1116         kill -USR1 $MULTIPID
1117 }
1118
1119 test_24q() {
1120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1121
1122         test_mkdir $DIR/R13a
1123         test_mkdir $DIR/R13b
1124         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1125         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1126         MULTIPID=$!
1127
1128         trap cleanup_multiop_pause EXIT
1129         mrename $DIR/R13a $DIR/R13b
1130         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1131         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1132         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1133         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1134         cleanup_multiop_pause
1135         wait $MULTIPID || error "multiop close failed"
1136 }
1137 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1138
1139 test_24r() { #bug 3789
1140         test_mkdir $DIR/R14a
1141         test_mkdir $DIR/R14a/b
1142         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1143         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1144         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1145 }
1146 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1147
1148 test_24s() {
1149         test_mkdir $DIR/R15a
1150         test_mkdir $DIR/R15a/b
1151         test_mkdir $DIR/R15a/b/c
1152         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1153         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1154         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1155 }
1156 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1157 test_24t() {
1158         test_mkdir $DIR/R16a
1159         test_mkdir $DIR/R16a/b
1160         test_mkdir $DIR/R16a/b/c
1161         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1162         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1163         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1164 }
1165 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1166
1167 test_24u() { # bug12192
1168         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1169         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1170 }
1171 run_test 24u "create stripe file"
1172
1173 simple_cleanup_common() {
1174         local createmany=$1
1175         local rc=0
1176
1177         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1178
1179         local start=$SECONDS
1180
1181         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1182         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1183         rc=$?
1184         wait_delete_completed
1185         echo "cleanup time $((SECONDS - start))"
1186         return $rc
1187 }
1188
1189 max_pages_per_rpc() {
1190         local mdtname="$(printf "MDT%04x" ${1:-0})"
1191         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1192 }
1193
1194 test_24v() {
1195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1196
1197         local nrfiles=${COUNT:-100000}
1198         local fname="$DIR/$tdir/$tfile"
1199
1200         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1201         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1202
1203         test_mkdir "$(dirname $fname)"
1204         # assume MDT0000 has the fewest inodes
1205         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1206         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1207         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1208
1209         stack_trap "simple_cleanup_common $nrfiles"
1210
1211         createmany -m "$fname" $nrfiles
1212
1213         cancel_lru_locks mdc
1214         lctl set_param mdc.*.stats clear
1215
1216         # was previously test_24D: LU-6101
1217         # readdir() returns correct number of entries after cursor reload
1218         local num_ls=$(ls $DIR/$tdir | wc -l)
1219         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1220         local num_all=$(ls -a $DIR/$tdir | wc -l)
1221         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1222                 [ $num_all -ne $((nrfiles + 2)) ]; then
1223                         error "Expected $nrfiles files, got $num_ls " \
1224                                 "($num_uniq unique $num_all .&..)"
1225         fi
1226         # LU-5 large readdir
1227         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1228         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1229         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1230         # take into account of overhead in lu_dirpage header and end mark in
1231         # each page, plus one in rpc_num calculation.
1232         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1233         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1234         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1235         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1236         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1237         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1238         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1239         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1240                 error "large readdir doesn't take effect: " \
1241                       "$mds_readpage should be about $rpc_max"
1242 }
1243 run_test 24v "list large directory (test hash collision, b=17560)"
1244
1245 test_24w() { # bug21506
1246         SZ1=234852
1247         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1248         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1249         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1250         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1251         [[ "$SZ1" -eq "$SZ2" ]] ||
1252                 error "Error reading at the end of the file $tfile"
1253 }
1254 run_test 24w "Reading a file larger than 4Gb"
1255
1256 test_24x() {
1257         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1259         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1260                 skip "Need MDS version at least 2.7.56"
1261
1262         local MDTIDX=1
1263         local remote_dir=$DIR/$tdir/remote_dir
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $MDTIDX $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $DIR/$tdir/src_dir
1270         touch $DIR/$tdir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename dir cross MDT failed!"
1276
1277         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1278                 error "rename file cross MDT failed!"
1279
1280         touch $DIR/$tdir/ln_file
1281         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1282                 error "ln file cross MDT failed"
1283
1284         rm -rf $DIR/$tdir || error "Can not delete directories"
1285 }
1286 run_test 24x "cross MDT rename/link"
1287
1288 test_24y() {
1289         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1291
1292         local remote_dir=$DIR/$tdir/remote_dir
1293         local mdtidx=1
1294
1295         test_mkdir $DIR/$tdir
1296         $LFS mkdir -i $mdtidx $remote_dir ||
1297                 error "create remote directory failed"
1298
1299         test_mkdir $remote_dir/src_dir
1300         touch $remote_dir/src_file
1301         test_mkdir $remote_dir/tgt_dir
1302         touch $remote_dir/tgt_file
1303
1304         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1305                 error "rename subdir in the same remote dir failed!"
1306
1307         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1308                 error "rename files in the same remote dir failed!"
1309
1310         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1311                 error "link files in the same remote dir failed!"
1312
1313         rm -rf $DIR/$tdir || error "Can not delete directories"
1314 }
1315 run_test 24y "rename/link on the same dir should succeed"
1316
1317 test_24z() {
1318         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1319         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1320                 skip "Need MDS version at least 2.12.51"
1321
1322         local index
1323
1324         for index in 0 1; do
1325                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1326                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1327         done
1328
1329         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1330
1331         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1332         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1333
1334         local mdts=$(comma_list $(mdts_nodes))
1335
1336         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1337         stack_trap "do_nodes $mdts $LCTL \
1338                 set_param mdt.*.enable_remote_rename=1" EXIT
1339
1340         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1341
1342         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1343         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1344 }
1345 run_test 24z "cross-MDT rename is done as cp"
1346
1347 test_24A() { # LU-3182
1348         local NFILES=5000
1349
1350         test_mkdir $DIR/$tdir
1351         stack_trap "simple_cleanup_common $NFILES"
1352         createmany -m $DIR/$tdir/$tfile $NFILES
1353         local t=$(ls $DIR/$tdir | wc -l)
1354         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1355         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1356
1357         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1358                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1359 }
1360 run_test 24A "readdir() returns correct number of entries."
1361
1362 test_24B() { # LU-4805
1363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1364
1365         local count
1366
1367         test_mkdir $DIR/$tdir
1368         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1369                 error "create striped dir failed"
1370
1371         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1372         [ $count -eq 2 ] || error "Expected 2, got $count"
1373
1374         touch $DIR/$tdir/striped_dir/a
1375
1376         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1377         [ $count -eq 3 ] || error "Expected 3, got $count"
1378
1379         touch $DIR/$tdir/striped_dir/.f
1380
1381         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1382         [ $count -eq 4 ] || error "Expected 4, got $count"
1383
1384         rm -rf $DIR/$tdir || error "Can not delete directories"
1385 }
1386 run_test 24B "readdir for striped dir return correct number of entries"
1387
1388 test_24C() {
1389         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1390
1391         mkdir $DIR/$tdir
1392         mkdir $DIR/$tdir/d0
1393         mkdir $DIR/$tdir/d1
1394
1395         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1396                 error "create striped dir failed"
1397
1398         cd $DIR/$tdir/d0/striped_dir
1399
1400         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1401         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1402         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1403
1404         [ "$d0_ino" = "$parent_ino" ] ||
1405                 error ".. wrong, expect $d0_ino, get $parent_ino"
1406
1407         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1408                 error "mv striped dir failed"
1409
1410         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1411
1412         [ "$d1_ino" = "$parent_ino" ] ||
1413                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1414 }
1415 run_test 24C "check .. in striped dir"
1416
1417 test_24E() {
1418         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1420
1421         mkdir -p $DIR/$tdir
1422         mkdir $DIR/$tdir/src_dir
1423         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1424                 error "create remote source failed"
1425
1426         touch $DIR/$tdir/src_dir/src_child/a
1427
1428         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1429                 error "create remote target dir failed"
1430
1431         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1432                 error "create remote target child failed"
1433
1434         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1435                 error "rename dir cross MDT failed!"
1436
1437         find $DIR/$tdir
1438
1439         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1440                 error "src_child still exists after rename"
1441
1442         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1443                 error "missing file(a) after rename"
1444
1445         rm -rf $DIR/$tdir || error "Can not delete directories"
1446 }
1447 run_test 24E "cross MDT rename/link"
1448
1449 test_24F () {
1450         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1451
1452         local repeats=1000
1453         [ "$SLOW" = "no" ] && repeats=100
1454
1455         mkdir -p $DIR/$tdir
1456
1457         echo "$repeats repeats"
1458         for ((i = 0; i < repeats; i++)); do
1459                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1460                 touch $DIR/$tdir/test/a || error "touch fails"
1461                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1462                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1463         done
1464
1465         true
1466 }
1467 run_test 24F "hash order vs readdir (LU-11330)"
1468
1469 test_24G () {
1470         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1471
1472         local ino1
1473         local ino2
1474
1475         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1476         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1477         touch $DIR/$tdir-0/f1 || error "touch f1"
1478         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1479         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1480         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1481         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1482         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1483 }
1484 run_test 24G "migrate symlink in rename"
1485
1486 test_24H() {
1487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1488         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1489                 skip "MDT1 should be on another node"
1490
1491         test_mkdir -i 1 -c 1 $DIR/$tdir
1492 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1493         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1494         touch $DIR/$tdir/$tfile || error "touch failed"
1495 }
1496 run_test 24H "repeat FLD_QUERY rpc"
1497
1498 test_25a() {
1499         echo '== symlink sanity ============================================='
1500
1501         test_mkdir $DIR/d25
1502         ln -s d25 $DIR/s25
1503         touch $DIR/s25/foo ||
1504                 error "File creation in symlinked directory failed"
1505 }
1506 run_test 25a "create file in symlinked directory ==============="
1507
1508 test_25b() {
1509         [ ! -d $DIR/d25 ] && test_25a
1510         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1511 }
1512 run_test 25b "lookup file in symlinked directory ==============="
1513
1514 test_26a() {
1515         test_mkdir $DIR/d26
1516         test_mkdir $DIR/d26/d26-2
1517         ln -s d26/d26-2 $DIR/s26
1518         touch $DIR/s26/foo || error "File creation failed"
1519 }
1520 run_test 26a "multiple component symlink ======================="
1521
1522 test_26b() {
1523         test_mkdir -p $DIR/$tdir/d26-2
1524         ln -s $tdir/d26-2/foo $DIR/s26-2
1525         touch $DIR/s26-2 || error "File creation failed"
1526 }
1527 run_test 26b "multiple component symlink at end of lookup ======"
1528
1529 test_26c() {
1530         test_mkdir $DIR/d26.2
1531         touch $DIR/d26.2/foo
1532         ln -s d26.2 $DIR/s26.2-1
1533         ln -s s26.2-1 $DIR/s26.2-2
1534         ln -s s26.2-2 $DIR/s26.2-3
1535         chmod 0666 $DIR/s26.2-3/foo
1536 }
1537 run_test 26c "chain of symlinks"
1538
1539 # recursive symlinks (bug 439)
1540 test_26d() {
1541         ln -s d26-3/foo $DIR/d26-3
1542 }
1543 run_test 26d "create multiple component recursive symlink"
1544
1545 test_26e() {
1546         [ ! -h $DIR/d26-3 ] && test_26d
1547         rm $DIR/d26-3
1548 }
1549 run_test 26e "unlink multiple component recursive symlink"
1550
1551 # recursive symlinks (bug 7022)
1552 test_26f() {
1553         test_mkdir $DIR/$tdir
1554         test_mkdir $DIR/$tdir/$tfile
1555         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1556         test_mkdir -p lndir/bar1
1557         test_mkdir $DIR/$tdir/$tfile/$tfile
1558         cd $tfile                || error "cd $tfile failed"
1559         ln -s .. dotdot          || error "ln dotdot failed"
1560         ln -s dotdot/lndir lndir || error "ln lndir failed"
1561         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1562         output=`ls $tfile/$tfile/lndir/bar1`
1563         [ "$output" = bar1 ] && error "unexpected output"
1564         rm -r $tfile             || error "rm $tfile failed"
1565         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1566 }
1567 run_test 26f "rm -r of a directory which has recursive symlink"
1568
1569 test_27a() {
1570         test_mkdir $DIR/$tdir
1571         $LFS getstripe $DIR/$tdir
1572         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1573         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1574         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1575 }
1576 run_test 27a "one stripe file"
1577
1578 test_27b() {
1579         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1580
1581         test_mkdir $DIR/$tdir
1582         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1583         $LFS getstripe -c $DIR/$tdir/$tfile
1584         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1585                 error "two-stripe file doesn't have two stripes"
1586
1587         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1588 }
1589 run_test 27b "create and write to two stripe file"
1590
1591 # 27c family tests specific striping, setstripe -o
1592 test_27ca() {
1593         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1594         test_mkdir -p $DIR/$tdir
1595         local osts="1"
1596
1597         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1598         $LFS getstripe -i $DIR/$tdir/$tfile
1599         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1600                 error "stripe not on specified OST"
1601
1602         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1603 }
1604 run_test 27ca "one stripe on specified OST"
1605
1606 test_27cb() {
1607         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1608         test_mkdir -p $DIR/$tdir
1609         local osts="1,0"
1610         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1611         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1612         echo "$getstripe"
1613
1614         # Strip getstripe output to a space separated list of OSTs
1615         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1616                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1617         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1618                 error "stripes not on specified OSTs"
1619
1620         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1621 }
1622 run_test 27cb "two stripes on specified OSTs"
1623
1624 test_27cc() {
1625         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1626         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1627                 skip "server does not support overstriping"
1628
1629         test_mkdir -p $DIR/$tdir
1630         local osts="0,0"
1631         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1632         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1633         echo "$getstripe"
1634
1635         # Strip getstripe output to a space separated list of OSTs
1636         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1637                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1638         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1639                 error "stripes not on specified OSTs"
1640
1641         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1642 }
1643 run_test 27cc "two stripes on the same OST"
1644
1645 test_27cd() {
1646         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1647         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1648                 skip "server does not support overstriping"
1649         test_mkdir -p $DIR/$tdir
1650         local osts="0,1,1,0"
1651         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1652         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1653         echo "$getstripe"
1654
1655         # Strip getstripe output to a space separated list of OSTs
1656         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1657                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1658         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1659                 error "stripes not on specified OSTs"
1660
1661         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1662 }
1663 run_test 27cd "four stripes on two OSTs"
1664
1665 test_27ce() {
1666         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1667                 skip_env "too many osts, skipping"
1668         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1669                 skip "server does not support overstriping"
1670         # We do one more stripe than we have OSTs
1671         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1672                 skip_env "ea_inode feature disabled"
1673
1674         test_mkdir -p $DIR/$tdir
1675         local osts=""
1676         for i in $(seq 0 $OSTCOUNT);
1677         do
1678                 osts=$osts"0"
1679                 if [ $i -ne $OSTCOUNT ]; then
1680                         osts=$osts","
1681                 fi
1682         done
1683         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1684         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1685         echo "$getstripe"
1686
1687         # Strip getstripe output to a space separated list of OSTs
1688         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1689                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1690         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1691                 error "stripes not on specified OSTs"
1692
1693         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1694 }
1695 run_test 27ce "more stripes than OSTs with -o"
1696
1697 test_27cf() {
1698         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1699         local pid=0
1700
1701         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1702         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1703         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1704         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1705                 error "failed to set $osp_proc=0"
1706
1707         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1708         pid=$!
1709         sleep 1
1710         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1711         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1712                 error "failed to set $osp_proc=1"
1713         wait $pid
1714         [[ $pid -ne 0 ]] ||
1715                 error "should return error due to $osp_proc=0"
1716 }
1717 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1718
1719 test_27d() {
1720         test_mkdir $DIR/$tdir
1721         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1722                 error "setstripe failed"
1723         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1724         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1725 }
1726 run_test 27d "create file with default settings"
1727
1728 test_27e() {
1729         # LU-5839 adds check for existed layout before setting it
1730         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1731                 skip "Need MDS version at least 2.7.56"
1732
1733         test_mkdir $DIR/$tdir
1734         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1735         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1736         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1737 }
1738 run_test 27e "setstripe existing file (should return error)"
1739
1740 test_27f() {
1741         test_mkdir $DIR/$tdir
1742         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1743                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1744         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1745                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1746         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1747         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1748 }
1749 run_test 27f "setstripe with bad stripe size (should return error)"
1750
1751 test_27g() {
1752         test_mkdir $DIR/$tdir
1753         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1754         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1755                 error "$DIR/$tdir/$tfile has object"
1756 }
1757 run_test 27g "$LFS getstripe with no objects"
1758
1759 test_27ga() {
1760         test_mkdir $DIR/$tdir
1761         touch $DIR/$tdir/$tfile || error "touch failed"
1762         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1763         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1764         local rc=$?
1765         (( rc == 2 )) || error "getstripe did not return ENOENT"
1766 }
1767 run_test 27ga "$LFS getstripe with missing file (should return error)"
1768
1769 test_27i() {
1770         test_mkdir $DIR/$tdir
1771         touch $DIR/$tdir/$tfile || error "touch failed"
1772         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1773                 error "missing objects"
1774 }
1775 run_test 27i "$LFS getstripe with some objects"
1776
1777 test_27j() {
1778         test_mkdir $DIR/$tdir
1779         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1780                 error "setstripe failed" || true
1781 }
1782 run_test 27j "setstripe with bad stripe offset (should return error)"
1783
1784 test_27k() { # bug 2844
1785         test_mkdir $DIR/$tdir
1786         local file=$DIR/$tdir/$tfile
1787         local ll_max_blksize=$((4 * 1024 * 1024))
1788         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1789         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1790         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1791         dd if=/dev/zero of=$file bs=4k count=1
1792         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1793         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1794 }
1795 run_test 27k "limit i_blksize for broken user apps"
1796
1797 test_27l() {
1798         mcreate $DIR/$tfile || error "creating file"
1799         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1800                 error "setstripe should have failed" || true
1801 }
1802 run_test 27l "check setstripe permissions (should return error)"
1803
1804 test_27m() {
1805         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1806
1807         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1808                 skip_env "multiple clients -- skipping"
1809
1810         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1811                    head -n1)
1812         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1813                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1814         fi
1815         stack_trap simple_cleanup_common
1816         test_mkdir $DIR/$tdir
1817         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1818         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1819                 error "dd should fill OST0"
1820         i=2
1821         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1822                 i=$((i + 1))
1823                 [ $i -gt 256 ] && break
1824         done
1825         i=$((i + 1))
1826         touch $DIR/$tdir/$tfile.$i
1827         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1828             awk '{print $1}'| grep -w "0") ] &&
1829                 error "OST0 was full but new created file still use it"
1830         i=$((i + 1))
1831         touch $DIR/$tdir/$tfile.$i
1832         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1833             awk '{print $1}'| grep -w "0") ] &&
1834                 error "OST0 was full but new created file still use it" || true
1835 }
1836 run_test 27m "create file while OST0 was full"
1837
1838 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1839 # if the OST isn't full anymore.
1840 reset_enospc() {
1841         local ostidx=${1:-""}
1842         local delay
1843         local ready
1844         local get_prealloc
1845
1846         local list=$(comma_list $(osts_nodes))
1847         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1848
1849         do_nodes $list lctl set_param fail_loc=0
1850         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1851         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1852                 awk '{print $1 * 2;exit;}')
1853         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1854                         grep -v \"^0$\""
1855         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1856 }
1857
1858 test_27n() {
1859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1861         remote_mds_nodsh && skip "remote MDS with nodsh"
1862         remote_ost_nodsh && skip "remote OST with nodsh"
1863
1864         reset_enospc
1865         rm -f $DIR/$tdir/$tfile
1866         exhaust_precreations 0 0x80000215
1867         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1868         touch $DIR/$tdir/$tfile || error "touch failed"
1869         $LFS getstripe $DIR/$tdir/$tfile
1870         reset_enospc
1871 }
1872 run_test 27n "create file with some full OSTs"
1873
1874 test_27o() {
1875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1877         remote_mds_nodsh && skip "remote MDS with nodsh"
1878         remote_ost_nodsh && skip "remote OST with nodsh"
1879
1880         reset_enospc
1881         rm -f $DIR/$tdir/$tfile
1882         exhaust_all_precreations 0x215
1883
1884         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1885
1886         reset_enospc
1887         rm -rf $DIR/$tdir/*
1888 }
1889 run_test 27o "create file with all full OSTs (should error)"
1890
1891 function create_and_checktime() {
1892         local fname=$1
1893         local loops=$2
1894         local i
1895
1896         for ((i=0; i < $loops; i++)); do
1897                 local start=$SECONDS
1898                 multiop $fname-$i Oc
1899                 ((SECONDS-start < TIMEOUT)) ||
1900                         error "creation took " $((SECONDS-$start)) && return 1
1901         done
1902 }
1903
1904 test_27oo() {
1905         local mdts=$(comma_list $(mdts_nodes))
1906
1907         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1908                 skip "Need MDS version at least 2.13.57"
1909
1910         local f0=$DIR/${tfile}-0
1911         local f1=$DIR/${tfile}-1
1912
1913         wait_delete_completed
1914
1915         # refill precreated objects
1916         $LFS setstripe -i0 -c1 $f0
1917
1918         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1919         # force QoS allocation policy
1920         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1921         stack_trap "do_nodes $mdts $LCTL set_param \
1922                 lov.*.qos_threshold_rr=$saved" EXIT
1923         sleep_maxage
1924
1925         # one OST is unavailable, but still have few objects preallocated
1926         stop ost1
1927         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1928                 rm -rf $f1 $DIR/$tdir*" EXIT
1929
1930         for ((i=0; i < 7; i++)); do
1931                 mkdir $DIR/$tdir$i || error "can't create dir"
1932                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1933                         error "can't set striping"
1934         done
1935         for ((i=0; i < 7; i++)); do
1936                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1937         done
1938         wait
1939 }
1940 run_test 27oo "don't let few threads to reserve too many objects"
1941
1942 test_27p() {
1943         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1945         remote_mds_nodsh && skip "remote MDS with nodsh"
1946         remote_ost_nodsh && skip "remote OST with nodsh"
1947
1948         reset_enospc
1949         rm -f $DIR/$tdir/$tfile
1950         test_mkdir $DIR/$tdir
1951
1952         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1953         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1954         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1955
1956         exhaust_precreations 0 0x80000215
1957         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1958         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1959         $LFS getstripe $DIR/$tdir/$tfile
1960
1961         reset_enospc
1962 }
1963 run_test 27p "append to a truncated file with some full OSTs"
1964
1965 test_27q() {
1966         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1968         remote_mds_nodsh && skip "remote MDS with nodsh"
1969         remote_ost_nodsh && skip "remote OST with nodsh"
1970
1971         reset_enospc
1972         rm -f $DIR/$tdir/$tfile
1973
1974         mkdir_on_mdt0 $DIR/$tdir
1975         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1976         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1977                 error "truncate $DIR/$tdir/$tfile failed"
1978         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1979
1980         exhaust_all_precreations 0x215
1981
1982         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1983         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1984
1985         reset_enospc
1986 }
1987 run_test 27q "append to truncated file with all OSTs full (should error)"
1988
1989 test_27r() {
1990         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1992         remote_mds_nodsh && skip "remote MDS with nodsh"
1993         remote_ost_nodsh && skip "remote OST with nodsh"
1994
1995         reset_enospc
1996         rm -f $DIR/$tdir/$tfile
1997         exhaust_precreations 0 0x80000215
1998
1999         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2000
2001         reset_enospc
2002 }
2003 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2004
2005 test_27s() { # bug 10725
2006         test_mkdir $DIR/$tdir
2007         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2008         local stripe_count=0
2009         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2010         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2011                 error "stripe width >= 2^32 succeeded" || true
2012
2013 }
2014 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2015
2016 test_27t() { # bug 10864
2017         WDIR=$(pwd)
2018         WLFS=$(which lfs)
2019         cd $DIR
2020         touch $tfile
2021         $WLFS getstripe $tfile
2022         cd $WDIR
2023 }
2024 run_test 27t "check that utils parse path correctly"
2025
2026 test_27u() { # bug 4900
2027         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2028         remote_mds_nodsh && skip "remote MDS with nodsh"
2029
2030         local index
2031         local list=$(comma_list $(mdts_nodes))
2032
2033 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2034         do_nodes $list $LCTL set_param fail_loc=0x139
2035         test_mkdir -p $DIR/$tdir
2036         stack_trap "simple_cleanup_common 1000"
2037         createmany -o $DIR/$tdir/$tfile 1000
2038         do_nodes $list $LCTL set_param fail_loc=0
2039
2040         TLOG=$TMP/$tfile.getstripe
2041         $LFS getstripe $DIR/$tdir > $TLOG
2042         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2043         [[ $OBJS -gt 0 ]] &&
2044                 error "$OBJS objects created on OST-0. See $TLOG" ||
2045                 rm -f $TLOG
2046 }
2047 run_test 27u "skip object creation on OSC w/o objects"
2048
2049 test_27v() { # bug 4900
2050         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2052         remote_mds_nodsh && skip "remote MDS with nodsh"
2053         remote_ost_nodsh && skip "remote OST with nodsh"
2054
2055         exhaust_all_precreations 0x215
2056         reset_enospc
2057
2058         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2059
2060         touch $DIR/$tdir/$tfile
2061         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2062         # all except ost1
2063         for (( i=1; i < OSTCOUNT; i++ )); do
2064                 do_facet ost$i lctl set_param fail_loc=0x705
2065         done
2066         local START=`date +%s`
2067         createmany -o $DIR/$tdir/$tfile 32
2068
2069         local FINISH=`date +%s`
2070         local TIMEOUT=`lctl get_param -n timeout`
2071         local PROCESS=$((FINISH - START))
2072         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2073                error "$FINISH - $START >= $TIMEOUT / 2"
2074         sleep $((TIMEOUT / 2 - PROCESS))
2075         reset_enospc
2076 }
2077 run_test 27v "skip object creation on slow OST"
2078
2079 test_27w() { # bug 10997
2080         test_mkdir $DIR/$tdir
2081         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2082         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2083                 error "stripe size $size != 65536" || true
2084         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2085                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2086 }
2087 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2088
2089 test_27wa() {
2090         [[ $OSTCOUNT -lt 2 ]] &&
2091                 skip_env "skipping multiple stripe count/offset test"
2092
2093         test_mkdir $DIR/$tdir
2094         for i in $(seq 1 $OSTCOUNT); do
2095                 offset=$((i - 1))
2096                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2097                         error "setstripe -c $i -i $offset failed"
2098                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2099                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2100                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2101                 [ $index -ne $offset ] &&
2102                         error "stripe offset $index != $offset" || true
2103         done
2104 }
2105 run_test 27wa "check $LFS setstripe -c -i options"
2106
2107 test_27x() {
2108         remote_ost_nodsh && skip "remote OST with nodsh"
2109         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2111
2112         OFFSET=$(($OSTCOUNT - 1))
2113         OSTIDX=0
2114         local OST=$(ostname_from_index $OSTIDX)
2115
2116         test_mkdir $DIR/$tdir
2117         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2118         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2119         sleep_maxage
2120         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2121         for i in $(seq 0 $OFFSET); do
2122                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2123                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2124                 error "OST0 was degraded but new created file still use it"
2125         done
2126         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2127 }
2128 run_test 27x "create files while OST0 is degraded"
2129
2130 test_27y() {
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         remote_mds_nodsh && skip "remote MDS with nodsh"
2133         remote_ost_nodsh && skip "remote OST with nodsh"
2134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2135
2136         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2137         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2138                 osp.$mdtosc.prealloc_last_id)
2139         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2140                 osp.$mdtosc.prealloc_next_id)
2141         local fcount=$((last_id - next_id))
2142         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2143         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2144
2145         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2146                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2147         local OST_DEACTIVE_IDX=-1
2148         local OSC
2149         local OSTIDX
2150         local OST
2151
2152         for OSC in $MDS_OSCS; do
2153                 OST=$(osc_to_ost $OSC)
2154                 OSTIDX=$(index_from_ostuuid $OST)
2155                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2156                         OST_DEACTIVE_IDX=$OSTIDX
2157                 fi
2158                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2159                         echo $OSC "is Deactivated:"
2160                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2161                 fi
2162         done
2163
2164         OSTIDX=$(index_from_ostuuid $OST)
2165         test_mkdir $DIR/$tdir
2166         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2167
2168         for OSC in $MDS_OSCS; do
2169                 OST=$(osc_to_ost $OSC)
2170                 OSTIDX=$(index_from_ostuuid $OST)
2171                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2172                         echo $OST "is degraded:"
2173                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2174                                                 obdfilter.$OST.degraded=1
2175                 fi
2176         done
2177
2178         sleep_maxage
2179         createmany -o $DIR/$tdir/$tfile $fcount
2180
2181         for OSC in $MDS_OSCS; do
2182                 OST=$(osc_to_ost $OSC)
2183                 OSTIDX=$(index_from_ostuuid $OST)
2184                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2185                         echo $OST "is recovered from degraded:"
2186                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2187                                                 obdfilter.$OST.degraded=0
2188                 else
2189                         do_facet $SINGLEMDS lctl --device %$OSC activate
2190                 fi
2191         done
2192
2193         # all osp devices get activated, hence -1 stripe count restored
2194         local stripe_count=0
2195
2196         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2197         # devices get activated.
2198         sleep_maxage
2199         $LFS setstripe -c -1 $DIR/$tfile
2200         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2201         rm -f $DIR/$tfile
2202         [ $stripe_count -ne $OSTCOUNT ] &&
2203                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2204         return 0
2205 }
2206 run_test 27y "create files while OST0 is degraded and the rest inactive"
2207
2208 check_seq_oid()
2209 {
2210         log "check file $1"
2211
2212         lmm_count=$($LFS getstripe -c $1)
2213         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2214         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2215
2216         local old_ifs="$IFS"
2217         IFS=$'[:]'
2218         fid=($($LFS path2fid $1))
2219         IFS="$old_ifs"
2220
2221         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2222         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2223
2224         # compare lmm_seq and lu_fid->f_seq
2225         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2226         # compare lmm_object_id and lu_fid->oid
2227         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2228
2229         # check the trusted.fid attribute of the OST objects of the file
2230         local have_obdidx=false
2231         local stripe_nr=0
2232         $LFS getstripe $1 | while read obdidx oid hex seq; do
2233                 # skip lines up to and including "obdidx"
2234                 [ -z "$obdidx" ] && break
2235                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2236                 $have_obdidx || continue
2237
2238                 local ost=$((obdidx + 1))
2239                 local dev=$(ostdevname $ost)
2240                 local oid_hex
2241
2242                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2243
2244                 seq=$(echo $seq | sed -e "s/^0x//g")
2245                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2246                         oid_hex=$(echo $oid)
2247                 else
2248                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2249                 fi
2250                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2251
2252                 local ff=""
2253                 #
2254                 # Don't unmount/remount the OSTs if we don't need to do that.
2255                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2256                 # update too, until that use mount/ll_decode_filter_fid/mount.
2257                 # Re-enable when debugfs will understand new filter_fid.
2258                 #
2259                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2260                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2261                                 $dev 2>/dev/null" | grep "parent=")
2262                 fi
2263                 if [ -z "$ff" ]; then
2264                         stop ost$ost
2265                         mount_fstype ost$ost
2266                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2267                                 $(facet_mntpt ost$ost)/$obj_file)
2268                         unmount_fstype ost$ost
2269                         start ost$ost $dev $OST_MOUNT_OPTS
2270                         clients_up
2271                 fi
2272
2273                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2274
2275                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2276
2277                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2278                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2279                 #
2280                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2281                 #       stripe_size=1048576 component_id=1 component_start=0 \
2282                 #       component_end=33554432
2283                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2284                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2285                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2286                 local ff_pstripe
2287                 if grep -q 'stripe=' <<<$ff; then
2288                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2289                 else
2290                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2291                         # into f_ver in this case.  See comment on ff_parent.
2292                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2293                 fi
2294
2295                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2296                 [ $ff_pseq = $lmm_seq ] ||
2297                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2298                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2299                 [ $ff_poid = $lmm_oid ] ||
2300                         error "FF parent OID $ff_poid != $lmm_oid"
2301                 (($ff_pstripe == $stripe_nr)) ||
2302                         error "FF stripe $ff_pstripe != $stripe_nr"
2303
2304                 stripe_nr=$((stripe_nr + 1))
2305                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2306                         continue
2307                 if grep -q 'stripe_count=' <<<$ff; then
2308                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2309                                             -e 's/ .*//' <<<$ff)
2310                         [ $lmm_count = $ff_scnt ] ||
2311                                 error "FF stripe count $lmm_count != $ff_scnt"
2312                 fi
2313         done
2314 }
2315
2316 test_27z() {
2317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2318         remote_ost_nodsh && skip "remote OST with nodsh"
2319
2320         test_mkdir $DIR/$tdir
2321         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2322                 { error "setstripe -c -1 failed"; return 1; }
2323         # We need to send a write to every object to get parent FID info set.
2324         # This _should_ also work for setattr, but does not currently.
2325         # touch $DIR/$tdir/$tfile-1 ||
2326         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2327                 { error "dd $tfile-1 failed"; return 2; }
2328         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2329                 { error "setstripe -c -1 failed"; return 3; }
2330         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2331                 { error "dd $tfile-2 failed"; return 4; }
2332
2333         # make sure write RPCs have been sent to OSTs
2334         sync; sleep 5; sync
2335
2336         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2337         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2338 }
2339 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2340
2341 test_27A() { # b=19102
2342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2343
2344         save_layout_restore_at_exit $MOUNT
2345         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2346         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2347                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2348         local default_size=$($LFS getstripe -S $MOUNT)
2349         local default_offset=$($LFS getstripe -i $MOUNT)
2350         local dsize=$(do_facet $SINGLEMDS \
2351                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2352         [ $default_size -eq $dsize ] ||
2353                 error "stripe size $default_size != $dsize"
2354         [ $default_offset -eq -1 ] ||
2355                 error "stripe offset $default_offset != -1"
2356 }
2357 run_test 27A "check filesystem-wide default LOV EA values"
2358
2359 test_27B() { # LU-2523
2360         test_mkdir $DIR/$tdir
2361         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2362         touch $DIR/$tdir/f0
2363         # open f1 with O_LOV_DELAY_CREATE
2364         # rename f0 onto f1
2365         # call setstripe ioctl on open file descriptor for f1
2366         # close
2367         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2368                 $DIR/$tdir/f0
2369
2370         rm -f $DIR/$tdir/f1
2371         # open f1 with O_LOV_DELAY_CREATE
2372         # unlink f1
2373         # call setstripe ioctl on open file descriptor for f1
2374         # close
2375         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2376
2377         # Allow multiop to fail in imitation of NFS's busted semantics.
2378         true
2379 }
2380 run_test 27B "call setstripe on open unlinked file/rename victim"
2381
2382 # 27C family tests full striping and overstriping
2383 test_27Ca() { #LU-2871
2384         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2385
2386         declare -a ost_idx
2387         local index
2388         local found
2389         local i
2390         local j
2391
2392         test_mkdir $DIR/$tdir
2393         cd $DIR/$tdir
2394         for i in $(seq 0 $((OSTCOUNT - 1))); do
2395                 # set stripe across all OSTs starting from OST$i
2396                 $LFS setstripe -i $i -c -1 $tfile$i
2397                 # get striping information
2398                 ost_idx=($($LFS getstripe $tfile$i |
2399                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2400                 echo "OST Index: ${ost_idx[*]}"
2401
2402                 # check the layout
2403                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2404                         error "${#ost_idx[@]} != $OSTCOUNT"
2405
2406                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2407                         found=0
2408                         for j in "${ost_idx[@]}"; do
2409                                 if [ $index -eq $j ]; then
2410                                         found=1
2411                                         break
2412                                 fi
2413                         done
2414                         [ $found = 1 ] ||
2415                                 error "Can not find $index in ${ost_idx[*]}"
2416                 done
2417         done
2418 }
2419 run_test 27Ca "check full striping across all OSTs"
2420
2421 test_27Cb() {
2422         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2423                 skip "server does not support overstriping"
2424         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2425                 skip_env "too many osts, skipping"
2426
2427         test_mkdir -p $DIR/$tdir
2428         local setcount=$(($OSTCOUNT * 2))
2429         [ $setcount -lt 160 ] || large_xattr_enabled ||
2430                 skip_env "ea_inode feature disabled"
2431
2432         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2433                 error "setstripe failed"
2434
2435         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2436         [ $count -eq $setcount ] ||
2437                 error "stripe count $count, should be $setcount"
2438
2439         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2440                 error "overstriped should be set in pattern"
2441
2442         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2443                 error "dd failed"
2444 }
2445 run_test 27Cb "more stripes than OSTs with -C"
2446
2447 test_27Cc() {
2448         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2449                 skip "server does not support overstriping"
2450         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2451
2452         test_mkdir -p $DIR/$tdir
2453         local setcount=$(($OSTCOUNT - 1))
2454
2455         [ $setcount -lt 160 ] || large_xattr_enabled ||
2456                 skip_env "ea_inode feature disabled"
2457
2458         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2459                 error "setstripe failed"
2460
2461         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2462         [ $count -eq $setcount ] ||
2463                 error "stripe count $count, should be $setcount"
2464
2465         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2466                 error "overstriped should not be set in pattern"
2467
2468         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2469                 error "dd failed"
2470 }
2471 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2472
2473 test_27Cd() {
2474         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2475                 skip "server does not support overstriping"
2476         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2477         large_xattr_enabled || skip_env "ea_inode feature disabled"
2478
2479         test_mkdir -p $DIR/$tdir
2480         local setcount=$LOV_MAX_STRIPE_COUNT
2481
2482         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2483                 error "setstripe failed"
2484
2485         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2486         [ $count -eq $setcount ] ||
2487                 error "stripe count $count, should be $setcount"
2488
2489         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2490                 error "overstriped should be set in pattern"
2491
2492         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2493                 error "dd failed"
2494
2495         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2496 }
2497 run_test 27Cd "test maximum stripe count"
2498
2499 test_27Ce() {
2500         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2501                 skip "server does not support overstriping"
2502         test_mkdir -p $DIR/$tdir
2503
2504         pool_add $TESTNAME || error "Pool creation failed"
2505         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2506
2507         local setcount=8
2508
2509         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2510                 error "setstripe failed"
2511
2512         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2513         [ $count -eq $setcount ] ||
2514                 error "stripe count $count, should be $setcount"
2515
2516         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2517                 error "overstriped should be set in pattern"
2518
2519         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2520                 error "dd failed"
2521
2522         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2523 }
2524 run_test 27Ce "test pool with overstriping"
2525
2526 test_27Cf() {
2527         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2528                 skip "server does not support overstriping"
2529         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2530                 skip_env "too many osts, skipping"
2531
2532         test_mkdir -p $DIR/$tdir
2533
2534         local setcount=$(($OSTCOUNT * 2))
2535         [ $setcount -lt 160 ] || large_xattr_enabled ||
2536                 skip_env "ea_inode feature disabled"
2537
2538         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2539                 error "setstripe failed"
2540
2541         echo 1 > $DIR/$tdir/$tfile
2542
2543         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2544         [ $count -eq $setcount ] ||
2545                 error "stripe count $count, should be $setcount"
2546
2547         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2548                 error "overstriped should be set in pattern"
2549
2550         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2551                 error "dd failed"
2552
2553         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2554 }
2555 run_test 27Cf "test default inheritance with overstriping"
2556
2557 test_27D() {
2558         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2559         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2560         remote_mds_nodsh && skip "remote MDS with nodsh"
2561
2562         local POOL=${POOL:-testpool}
2563         local first_ost=0
2564         local last_ost=$(($OSTCOUNT - 1))
2565         local ost_step=1
2566         local ost_list=$(seq $first_ost $ost_step $last_ost)
2567         local ost_range="$first_ost $last_ost $ost_step"
2568
2569         test_mkdir $DIR/$tdir
2570         pool_add $POOL || error "pool_add failed"
2571         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2572
2573         local skip27D
2574         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2575                 skip27D+="-s 29"
2576         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2577                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2578                         skip27D+=" -s 30,31"
2579         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2580           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2581                 skip27D+=" -s 32,33"
2582         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2583                 skip27D+=" -s 34"
2584         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2585                 error "llapi_layout_test failed"
2586
2587         destroy_test_pools || error "destroy test pools failed"
2588 }
2589 run_test 27D "validate llapi_layout API"
2590
2591 # Verify that default_easize is increased from its initial value after
2592 # accessing a widely striped file.
2593 test_27E() {
2594         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2595         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2596                 skip "client does not have LU-3338 fix"
2597
2598         # 72 bytes is the minimum space required to store striping
2599         # information for a file striped across one OST:
2600         # (sizeof(struct lov_user_md_v3) +
2601         #  sizeof(struct lov_user_ost_data_v1))
2602         local min_easize=72
2603         $LCTL set_param -n llite.*.default_easize $min_easize ||
2604                 error "lctl set_param failed"
2605         local easize=$($LCTL get_param -n llite.*.default_easize)
2606
2607         [ $easize -eq $min_easize ] ||
2608                 error "failed to set default_easize"
2609
2610         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2611                 error "setstripe failed"
2612         # In order to ensure stat() call actually talks to MDS we need to
2613         # do something drastic to this file to shake off all lock, e.g.
2614         # rename it (kills lookup lock forcing cache cleaning)
2615         mv $DIR/$tfile $DIR/${tfile}-1
2616         ls -l $DIR/${tfile}-1
2617         rm $DIR/${tfile}-1
2618
2619         easize=$($LCTL get_param -n llite.*.default_easize)
2620
2621         [ $easize -gt $min_easize ] ||
2622                 error "default_easize not updated"
2623 }
2624 run_test 27E "check that default extended attribute size properly increases"
2625
2626 test_27F() { # LU-5346/LU-7975
2627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2628         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2629         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2630                 skip "Need MDS version at least 2.8.51"
2631         remote_ost_nodsh && skip "remote OST with nodsh"
2632
2633         test_mkdir $DIR/$tdir
2634         rm -f $DIR/$tdir/f0
2635         $LFS setstripe -c 2 $DIR/$tdir
2636
2637         # stop all OSTs to reproduce situation for LU-7975 ticket
2638         for num in $(seq $OSTCOUNT); do
2639                 stop ost$num
2640         done
2641
2642         # open/create f0 with O_LOV_DELAY_CREATE
2643         # truncate f0 to a non-0 size
2644         # close
2645         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2646
2647         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2648         # open/write it again to force delayed layout creation
2649         cat /etc/hosts > $DIR/$tdir/f0 &
2650         catpid=$!
2651
2652         # restart OSTs
2653         for num in $(seq $OSTCOUNT); do
2654                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2655                         error "ost$num failed to start"
2656         done
2657
2658         wait $catpid || error "cat failed"
2659
2660         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2661         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2662                 error "wrong stripecount"
2663
2664 }
2665 run_test 27F "Client resend delayed layout creation with non-zero size"
2666
2667 test_27G() { #LU-10629
2668         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2669                 skip "Need MDS version at least 2.11.51"
2670         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2671         remote_mds_nodsh && skip "remote MDS with nodsh"
2672         local POOL=${POOL:-testpool}
2673         local ostrange="0 0 1"
2674
2675         test_mkdir $DIR/$tdir
2676         touch $DIR/$tdir/$tfile.nopool
2677         pool_add $POOL || error "pool_add failed"
2678         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2679         $LFS setstripe -p $POOL $DIR/$tdir
2680
2681         local pool=$($LFS getstripe -p $DIR/$tdir)
2682
2683         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2684         touch $DIR/$tdir/$tfile.default
2685         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2686         $LFS find $DIR/$tdir -type f --pool $POOL
2687         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2688         [[ "$found" == "2" ]] ||
2689                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2690
2691         $LFS setstripe -d $DIR/$tdir
2692
2693         pool=$($LFS getstripe -p -d $DIR/$tdir)
2694
2695         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2696 }
2697 run_test 27G "Clear OST pool from stripe"
2698
2699 test_27H() {
2700         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2701                 skip "Need MDS version newer than 2.11.54"
2702         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2703         test_mkdir $DIR/$tdir
2704         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2705         touch $DIR/$tdir/$tfile
2706         $LFS getstripe -c $DIR/$tdir/$tfile
2707         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2708                 error "two-stripe file doesn't have two stripes"
2709
2710         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2711         $LFS getstripe -y $DIR/$tdir/$tfile
2712         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2713              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2714                 error "expected l_ost_idx: [02]$ not matched"
2715
2716         # make sure ost list has been cleared
2717         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2718         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2719                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2720         touch $DIR/$tdir/f3
2721         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2722 }
2723 run_test 27H "Set specific OSTs stripe"
2724
2725 test_27I() {
2726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2727         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2728         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2729                 skip "Need MDS version newer than 2.12.52"
2730         local pool=$TESTNAME
2731         local ostrange="1 1 1"
2732
2733         save_layout_restore_at_exit $MOUNT
2734         $LFS setstripe -c 2 -i 0 $MOUNT
2735         pool_add $pool || error "pool_add failed"
2736         pool_add_targets $pool $ostrange ||
2737                 error "pool_add_targets failed"
2738         test_mkdir $DIR/$tdir
2739         $LFS setstripe -p $pool $DIR/$tdir
2740         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2741         $LFS getstripe $DIR/$tdir/$tfile
2742 }
2743 run_test 27I "check that root dir striping does not break parent dir one"
2744
2745 test_27J() {
2746         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2747                 skip "Need MDS version newer than 2.12.51"
2748
2749         test_mkdir $DIR/$tdir
2750         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2751         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2752
2753         # create foreign file (raw way)
2754         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2755                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2756
2757         ! $LFS setstripe --foreign --flags foo \
2758                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2759                         error "creating $tfile with '--flags foo' should fail"
2760
2761         ! $LFS setstripe --foreign --flags 0xffffffff \
2762                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2763                         error "creating $tfile w/ 0xffffffff flags should fail"
2764
2765         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2766                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2767
2768         # verify foreign file (raw way)
2769         parse_foreign_file -f $DIR/$tdir/$tfile |
2770                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2771                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2772         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2773                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2774         parse_foreign_file -f $DIR/$tdir/$tfile |
2775                 grep "lov_foreign_size: 73" ||
2776                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2777         parse_foreign_file -f $DIR/$tdir/$tfile |
2778                 grep "lov_foreign_type: 1" ||
2779                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2780         parse_foreign_file -f $DIR/$tdir/$tfile |
2781                 grep "lov_foreign_flags: 0x0000DA08" ||
2782                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2783         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2784                 grep "lov_foreign_value: 0x" |
2785                 sed -e 's/lov_foreign_value: 0x//')
2786         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2787         [[ $lov = ${lov2// /} ]] ||
2788                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2789
2790         # create foreign file (lfs + API)
2791         $LFS setstripe --foreign=none --flags 0xda08 \
2792                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2793                 error "$DIR/$tdir/${tfile}2: create failed"
2794
2795         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2796                 grep "lfm_magic:.*0x0BD70BD0" ||
2797                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2798         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2799         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2800                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2801         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2802                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2803         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2804                 grep "lfm_flags:.*0x0000DA08" ||
2805                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2806         $LFS getstripe $DIR/$tdir/${tfile}2 |
2807                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2808                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2809
2810         # modify striping should fail
2811         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2812                 error "$DIR/$tdir/$tfile: setstripe should fail"
2813         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2814                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2815
2816         # R/W should fail
2817         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2818         cat $DIR/$tdir/${tfile}2 &&
2819                 error "$DIR/$tdir/${tfile}2: read should fail"
2820         cat /etc/passwd > $DIR/$tdir/$tfile &&
2821                 error "$DIR/$tdir/$tfile: write should fail"
2822         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2823                 error "$DIR/$tdir/${tfile}2: write should fail"
2824
2825         # chmod should work
2826         chmod 222 $DIR/$tdir/$tfile ||
2827                 error "$DIR/$tdir/$tfile: chmod failed"
2828         chmod 222 $DIR/$tdir/${tfile}2 ||
2829                 error "$DIR/$tdir/${tfile}2: chmod failed"
2830
2831         # chown should work
2832         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2833                 error "$DIR/$tdir/$tfile: chown failed"
2834         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2835                 error "$DIR/$tdir/${tfile}2: chown failed"
2836
2837         # rename should work
2838         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2839                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2840         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2841                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2842
2843         #remove foreign file
2844         rm $DIR/$tdir/${tfile}.new ||
2845                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2846         rm $DIR/$tdir/${tfile}2.new ||
2847                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2848 }
2849 run_test 27J "basic ops on file with foreign LOV"
2850
2851 test_27K() {
2852         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2853                 skip "Need MDS version newer than 2.12.49"
2854
2855         test_mkdir $DIR/$tdir
2856         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2857         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2858
2859         # create foreign dir (raw way)
2860         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2861                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2862
2863         ! $LFS setdirstripe --foreign --flags foo \
2864                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2865                         error "creating $tdir with '--flags foo' should fail"
2866
2867         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2868                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2869                         error "creating $tdir w/ 0xffffffff flags should fail"
2870
2871         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2872                 error "create_foreign_dir FAILED"
2873
2874         # verify foreign dir (raw way)
2875         parse_foreign_dir -d $DIR/$tdir/$tdir |
2876                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2877                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2878         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2879                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2880         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2881                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2882         parse_foreign_dir -d $DIR/$tdir/$tdir |
2883                 grep "lmv_foreign_flags: 55813$" ||
2884                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2885         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2886                 grep "lmv_foreign_value: 0x" |
2887                 sed 's/lmv_foreign_value: 0x//')
2888         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2889                 sed 's/ //g')
2890         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2891
2892         # create foreign dir (lfs + API)
2893         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2894                 $DIR/$tdir/${tdir}2 ||
2895                 error "$DIR/$tdir/${tdir}2: create failed"
2896
2897         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2898
2899         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2900                 grep "lfm_magic:.*0x0CD50CD0" ||
2901                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2902         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2903         # - sizeof(lfm_type) - sizeof(lfm_flags)
2904         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2905                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2906         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2908         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2909                 grep "lfm_flags:.*0x0000DA05" ||
2910                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2911         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2912                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2913                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2914
2915         # file create in dir should fail
2916         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2917         touch $DIR/$tdir/${tdir}2/$tfile &&
2918                 error "$DIR/${tdir}2: file create should fail"
2919
2920         # chmod should work
2921         chmod 777 $DIR/$tdir/$tdir ||
2922                 error "$DIR/$tdir: chmod failed"
2923         chmod 777 $DIR/$tdir/${tdir}2 ||
2924                 error "$DIR/${tdir}2: chmod failed"
2925
2926         # chown should work
2927         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2928                 error "$DIR/$tdir: chown failed"
2929         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2930                 error "$DIR/${tdir}2: chown failed"
2931
2932         # rename should work
2933         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2934                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2935         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2936                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2937
2938         #remove foreign dir
2939         rmdir $DIR/$tdir/${tdir}.new ||
2940                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2941         rmdir $DIR/$tdir/${tdir}2.new ||
2942                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2943 }
2944 run_test 27K "basic ops on dir with foreign LMV"
2945
2946 test_27L() {
2947         remote_mds_nodsh && skip "remote MDS with nodsh"
2948
2949         local POOL=${POOL:-$TESTNAME}
2950
2951         pool_add $POOL || error "pool_add failed"
2952
2953         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2954                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2955                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2956 }
2957 run_test 27L "lfs pool_list gives correct pool name"
2958
2959 test_27M() {
2960         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2961                 skip "Need MDS version >= than 2.12.57"
2962         remote_mds_nodsh && skip "remote MDS with nodsh"
2963         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2964
2965         # Set default striping on directory
2966         local setcount=4
2967         local stripe_opt
2968         local mdts=$(comma_list $(mdts_nodes))
2969
2970         # if we run against a 2.12 server which lacks overstring support
2971         # then the connect_flag will not report overstriping, even if client
2972         # is 2.14+
2973         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2974                 stripe_opt="-C $setcount"
2975         elif (( $OSTCOUNT >= $setcount )); then
2976                 stripe_opt="-c $setcount"
2977         else
2978                 skip "server does not support overstriping"
2979         fi
2980
2981         test_mkdir $DIR/$tdir
2982
2983         # Validate existing append_* params and ensure restore
2984         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2985         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2986         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2987
2988         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2989         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2990         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2991
2992         $LFS setstripe $stripe_opt $DIR/$tdir
2993
2994         echo 1 > $DIR/$tdir/${tfile}.1
2995         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2996         [ $count -eq $setcount ] ||
2997                 error "(1) stripe count $count, should be $setcount"
2998
2999         local appendcount=$orig_count
3000         echo 1 >> $DIR/$tdir/${tfile}.2_append
3001         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3002         [ $count -eq $appendcount ] ||
3003                 error "(2)stripe count $count, should be $appendcount for append"
3004
3005         # Disable O_APPEND striping, verify it works
3006         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3007
3008         # Should now get the default striping, which is 4
3009         setcount=4
3010         echo 1 >> $DIR/$tdir/${tfile}.3_append
3011         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3012         [ $count -eq $setcount ] ||
3013                 error "(3) stripe count $count, should be $setcount"
3014
3015         # Try changing the stripe count for append files
3016         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3017
3018         # Append striping is now 2 (directory default is still 4)
3019         appendcount=2
3020         echo 1 >> $DIR/$tdir/${tfile}.4_append
3021         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3022         [ $count -eq $appendcount ] ||
3023                 error "(4) stripe count $count, should be $appendcount for append"
3024
3025         # Test append stripe count of -1
3026         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3027         appendcount=$OSTCOUNT
3028         echo 1 >> $DIR/$tdir/${tfile}.5
3029         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3030         [ $count -eq $appendcount ] ||
3031                 error "(5) stripe count $count, should be $appendcount for append"
3032
3033         # Set append striping back to default of 1
3034         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3035
3036         # Try a new default striping, PFL + DOM
3037         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3038
3039         # Create normal DOM file, DOM returns stripe count == 0
3040         setcount=0
3041         touch $DIR/$tdir/${tfile}.6
3042         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3043         [ $count -eq $setcount ] ||
3044                 error "(6) stripe count $count, should be $setcount"
3045
3046         # Show
3047         appendcount=1
3048         echo 1 >> $DIR/$tdir/${tfile}.7_append
3049         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3050         [ $count -eq $appendcount ] ||
3051                 error "(7) stripe count $count, should be $appendcount for append"
3052
3053         # Clean up DOM layout
3054         $LFS setstripe -d $DIR/$tdir
3055
3056         save_layout_restore_at_exit $MOUNT
3057         # Now test that append striping works when layout is from root
3058         $LFS setstripe -c 2 $MOUNT
3059         # Make a special directory for this
3060         mkdir $DIR/${tdir}/${tdir}.2
3061
3062         # Verify for normal file
3063         setcount=2
3064         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3065         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3066         [ $count -eq $setcount ] ||
3067                 error "(8) stripe count $count, should be $setcount"
3068
3069         appendcount=1
3070         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3071         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3072         [ $count -eq $appendcount ] ||
3073                 error "(9) stripe count $count, should be $appendcount for append"
3074
3075         # Now test O_APPEND striping with pools
3076         pool_add $TESTNAME || error "pool creation failed"
3077         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3078         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3079
3080         echo 1 >> $DIR/$tdir/${tfile}.10_append
3081
3082         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3083         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3084
3085         # Check that count is still correct
3086         appendcount=1
3087         echo 1 >> $DIR/$tdir/${tfile}.11_append
3088         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3089         [ $count -eq $appendcount ] ||
3090                 error "(11) stripe count $count, should be $appendcount for append"
3091
3092         # Disable O_APPEND stripe count, verify pool works separately
3093         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3094
3095         echo 1 >> $DIR/$tdir/${tfile}.12_append
3096
3097         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3098         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3099
3100         # Remove pool setting, verify it's not applied
3101         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3102
3103         echo 1 >> $DIR/$tdir/${tfile}.13_append
3104
3105         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3106         [ "$pool" = "" ] || error "(13) pool found: $pool"
3107 }
3108 run_test 27M "test O_APPEND striping"
3109
3110 test_27N() {
3111         combined_mgs_mds && skip "needs separate MGS/MDT"
3112
3113         pool_add $TESTNAME || error "pool_add failed"
3114         do_facet mgs "$LCTL pool_list $FSNAME" |
3115                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3116                 error "lctl pool_list on MGS failed"
3117 }
3118 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3119
3120 clean_foreign_symlink() {
3121         trap 0
3122         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3123         for i in $DIR/$tdir/* ; do
3124                 $LFS unlink_foreign $i || true
3125         done
3126 }
3127
3128 test_27O() {
3129         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3130                 skip "Need MDS version newer than 2.12.51"
3131
3132         test_mkdir $DIR/$tdir
3133         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3134         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3135
3136         trap clean_foreign_symlink EXIT
3137
3138         # enable foreign_symlink behaviour
3139         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3140
3141         # foreign symlink LOV format is a partial path by default
3142
3143         # create foreign file (lfs + API)
3144         $LFS setstripe --foreign=symlink --flags 0xda05 \
3145                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3146                 error "$DIR/$tdir/${tfile}: create failed"
3147
3148         $LFS getstripe -v $DIR/$tdir/${tfile} |
3149                 grep "lfm_magic:.*0x0BD70BD0" ||
3150                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3151         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3153         $LFS getstripe -v $DIR/$tdir/${tfile} |
3154                 grep "lfm_flags:.*0x0000DA05" ||
3155                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3156         $LFS getstripe $DIR/$tdir/${tfile} |
3157                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3158                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3159
3160         # modify striping should fail
3161         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3162                 error "$DIR/$tdir/$tfile: setstripe should fail"
3163
3164         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3165         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3166         cat /etc/passwd > $DIR/$tdir/$tfile &&
3167                 error "$DIR/$tdir/$tfile: write should fail"
3168
3169         # rename should succeed
3170         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3171                 error "$DIR/$tdir/$tfile: rename has failed"
3172
3173         #remove foreign_symlink file should fail
3174         rm $DIR/$tdir/${tfile}.new &&
3175                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3176
3177         #test fake symlink
3178         mkdir /tmp/${uuid1} ||
3179                 error "/tmp/${uuid1}: mkdir has failed"
3180         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3181                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3182         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3183         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3185         #read should succeed now
3186         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3187                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3188         #write should succeed now
3189         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3190                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3191         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3193         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3194                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3195
3196         #check that getstripe still works
3197         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3198                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3199
3200         # chmod should still succeed
3201         chmod 644 $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3203
3204         # chown should still succeed
3205         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3207
3208         # rename should still succeed
3209         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3210                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3211
3212         #remove foreign_symlink file should still fail
3213         rm $DIR/$tdir/${tfile} &&
3214                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3215
3216         #use special ioctl() to unlink foreign_symlink file
3217         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3218                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3219
3220 }
3221 run_test 27O "basic ops on foreign file of symlink type"
3222
3223 test_27P() {
3224         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3225                 skip "Need MDS version newer than 2.12.49"
3226
3227         test_mkdir $DIR/$tdir
3228         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3229         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3230
3231         trap clean_foreign_symlink EXIT
3232
3233         # enable foreign_symlink behaviour
3234         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3235
3236         # foreign symlink LMV format is a partial path by default
3237
3238         # create foreign dir (lfs + API)
3239         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3240                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3241                 error "$DIR/$tdir/${tdir}: create failed"
3242
3243         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3244
3245         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3246                 grep "lfm_magic:.*0x0CD50CD0" ||
3247                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3248         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3251                 grep "lfm_flags:.*0x0000DA05" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3253         $LFS getdirstripe $DIR/$tdir/${tdir} |
3254                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3255                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3256
3257         # file create in dir should fail
3258         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3259         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3260
3261         # rename should succeed
3262         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3263                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3264
3265         #remove foreign_symlink dir should fail
3266         rmdir $DIR/$tdir/${tdir}.new &&
3267                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3268
3269         #test fake symlink
3270         mkdir -p /tmp/${uuid1}/${uuid2} ||
3271                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3272         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3273                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3274         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3275         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3277         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3278                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3279
3280         #check that getstripe fails now that foreign_symlink enabled
3281         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3282                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3283
3284         # file create in dir should work now
3285         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3286                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3287         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3289         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3290                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3291
3292         # chmod should still succeed
3293         chmod 755 $DIR/$tdir/${tdir}.new ||
3294                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3295
3296         # chown should still succeed
3297         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3298                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3299
3300         # rename should still succeed
3301         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3302                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3303
3304         #remove foreign_symlink dir should still fail
3305         rmdir $DIR/$tdir/${tdir} &&
3306                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3307
3308         #use special ioctl() to unlink foreign_symlink file
3309         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3310                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3311
3312         #created file should still exist
3313         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3314                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3315         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3317 }
3318 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3319
3320 test_27Q() {
3321         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3322         stack_trap "rm -f $TMP/$tfile*"
3323
3324         test_mkdir $DIR/$tdir-1
3325         test_mkdir $DIR/$tdir-2
3326
3327         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3328         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3329
3330         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3331         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3332
3333         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3334         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3335
3336         # Create some bad symlinks and ensure that we don't loop
3337         # forever or something. These should return ELOOP (40) and
3338         # ENOENT (2) but I don't want to test for that because there's
3339         # always some weirdo architecture that needs to ruin
3340         # everything by defining these error numbers differently.
3341
3342         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3343         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3344
3345         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3346         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3347
3348         return 0
3349 }
3350 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3351
3352 test_27R() {
3353         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3354                 skip "need MDS 2.14.55 or later"
3355         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3356
3357         local testdir="$DIR/$tdir"
3358         test_mkdir -p $testdir
3359         stack_trap "rm -rf $testdir"
3360         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3361
3362         local f1="$testdir/f1"
3363         touch $f1 || error "failed to touch $f1"
3364         local count=$($LFS getstripe -c $f1)
3365         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3366
3367         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3368         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3369
3370         local maxcount=$(($OSTCOUNT - 1))
3371         local mdts=$(comma_list $(mdts_nodes))
3372         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3373         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3374
3375         local f2="$testdir/f2"
3376         touch $f2 || error "failed to touch $f2"
3377         local count=$($LFS getstripe -c $f2)
3378         (( $count == $maxcount )) || error "wrong stripe count"
3379 }
3380 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3381
3382 test_27S() {
3383         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3384                 skip "Need MDS version at least 2.14.54"
3385         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3386                 skip "needs different host for mdt1 ost1"
3387
3388         local count=$(precreated_ost_obj_count 0 0)
3389
3390         echo "precreate count $count"
3391         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3392         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3393         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3394         do_facet mds1 $LCTL set_param fail_loc=0x2109
3395         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3396         do_facet ost1 $LCTL set_param fail_loc=0x252
3397         createmany -o $DIR/$tdir/f $count &
3398         pid=$!
3399         echo "precreate count $(precreated_ost_obj_count 0 0)"
3400         do_facet mds1 $LCTL set_param fail_loc=0
3401         do_facet ost1 $LCTL set_param fail_loc=0
3402         wait $pid || error "createmany failed"
3403         echo "precreate count $(precreated_ost_obj_count 0 0)"
3404 }
3405 run_test 27S "don't deactivate OSP on network issue"
3406
3407 test_27T() {
3408         [ $(facet_host client) == $(facet_host ost1) ] &&
3409                 skip "need ost1 and client on different nodes"
3410
3411 #define OBD_FAIL_OSC_NO_GRANT            0x411
3412         $LCTL set_param fail_loc=0x20000411 fail_val=1
3413 #define OBD_FAIL_OST_ENOSPC              0x215
3414         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3415         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3416         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3417                 error "multiop failed"
3418 }
3419 run_test 27T "no eio on close on partial write due to enosp"
3420
3421 test_27U() {
3422         local dir=$DIR/$tdir
3423         local file=$dir/$tfile
3424         local append_pool=${TESTNAME}-append
3425         local normal_pool=${TESTNAME}-normal
3426         local pool
3427         local stripe_count
3428         local stripe_count2
3429         local mdts=$(comma_list $(mdts_nodes))
3430
3431         # FIMXE
3432         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3433         #       skip "Need MDS version at least 2.15.42"
3434
3435         # Validate existing append_* params and ensure restore
3436         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3437         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3438         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3439
3440         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3441         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3442         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3443
3444         pool_add $append_pool || error "pool creation failed"
3445         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3446
3447         pool_add $normal_pool || error "pool creation failed"
3448         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3449
3450         test_mkdir $dir
3451         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3452
3453         echo XXX >> $file.1
3454         $LFS getstripe $file.1
3455
3456         pool=$($LFS getstripe -p $file.1)
3457         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3458
3459         stripe_count2=$($LFS getstripe -c $file.1)
3460         ((stripe_count2 == stripe_count)) ||
3461                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3462
3463         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3464
3465         echo XXX >> $file.2
3466         $LFS getstripe $file.2
3467
3468         pool=$($LFS getstripe -p $file.2)
3469         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3470
3471         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3472
3473         echo XXX >> $file.3
3474         $LFS getstripe $file.3
3475
3476         stripe_count2=$($LFS getstripe -c $file.3)
3477         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3478 }
3479 run_test 27U "append pool and stripe count work with composite default layout"
3480
3481 # createtest also checks that device nodes are created and
3482 # then visible correctly (#2091)
3483 test_28() { # bug 2091
3484         test_mkdir $DIR/d28
3485         $CREATETEST $DIR/d28/ct || error "createtest failed"
3486 }
3487 run_test 28 "create/mknod/mkdir with bad file types ============"
3488
3489 test_29() {
3490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3491
3492         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3493                 disable_opencache
3494                 stack_trap "restore_opencache"
3495         }
3496
3497         sync; sleep 1; sync # flush out any dirty pages from previous tests
3498         cancel_lru_locks
3499         test_mkdir $DIR/d29
3500         touch $DIR/d29/foo
3501         log 'first d29'
3502         ls -l $DIR/d29
3503
3504         declare -i LOCKCOUNTORIG=0
3505         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3506                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3507         done
3508         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3509
3510         declare -i LOCKUNUSEDCOUNTORIG=0
3511         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3512                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3513         done
3514
3515         log 'second d29'
3516         ls -l $DIR/d29
3517         log 'done'
3518
3519         declare -i LOCKCOUNTCURRENT=0
3520         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3521                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3522         done
3523
3524         declare -i LOCKUNUSEDCOUNTCURRENT=0
3525         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3526                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3527         done
3528
3529         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3530                 $LCTL set_param -n ldlm.dump_namespaces ""
3531                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3532                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3533                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3534                 return 2
3535         fi
3536         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3537                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3538                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3539                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3540                 return 3
3541         fi
3542 }
3543 run_test 29 "IT_GETATTR regression  ============================"
3544
3545 test_30a() { # was test_30
3546         cp $(which ls) $DIR || cp /bin/ls $DIR
3547         $DIR/ls / || error "Can't execute binary from lustre"
3548         rm $DIR/ls
3549 }
3550 run_test 30a "execute binary from Lustre (execve) =============="
3551
3552 test_30b() {
3553         cp `which ls` $DIR || cp /bin/ls $DIR
3554         chmod go+rx $DIR/ls
3555         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3556         rm $DIR/ls
3557 }
3558 run_test 30b "execute binary from Lustre as non-root ==========="
3559
3560 test_30c() { # b=22376
3561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3562
3563         cp $(which ls) $DIR || cp /bin/ls $DIR
3564         chmod a-rw $DIR/ls
3565         cancel_lru_locks mdc
3566         cancel_lru_locks osc
3567         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3568         rm -f $DIR/ls
3569 }
3570 run_test 30c "execute binary from Lustre without read perms ===="
3571
3572 test_30d() {
3573         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3574
3575         for i in {1..10}; do
3576                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3577                 local PID=$!
3578                 sleep 1
3579                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3580                 wait $PID || error "executing dd from Lustre failed"
3581                 rm -f $DIR/$tfile
3582         done
3583
3584         rm -f $DIR/dd
3585 }
3586 run_test 30d "execute binary from Lustre while clear locks"
3587
3588 test_31a() {
3589         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3590         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3591 }
3592 run_test 31a "open-unlink file =================================="
3593
3594 test_31b() {
3595         touch $DIR/f31 || error "touch $DIR/f31 failed"
3596         ln $DIR/f31 $DIR/f31b || error "ln failed"
3597         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3598         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3599 }
3600 run_test 31b "unlink file with multiple links while open ======="
3601
3602 test_31c() {
3603         touch $DIR/f31 || error "touch $DIR/f31 failed"
3604         ln $DIR/f31 $DIR/f31c || error "ln failed"
3605         multiop_bg_pause $DIR/f31 O_uc ||
3606                 error "multiop_bg_pause for $DIR/f31 failed"
3607         MULTIPID=$!
3608         $MULTIOP $DIR/f31c Ouc
3609         kill -USR1 $MULTIPID
3610         wait $MULTIPID
3611 }
3612 run_test 31c "open-unlink file with multiple links ============="
3613
3614 test_31d() {
3615         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3616         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3617 }
3618 run_test 31d "remove of open directory ========================="
3619
3620 test_31e() { # bug 2904
3621         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3622 }
3623 run_test 31e "remove of open non-empty directory ==============="
3624
3625 test_31f() { # bug 4554
3626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3627
3628         set -vx
3629         test_mkdir $DIR/d31f
3630         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3631         cp /etc/hosts $DIR/d31f
3632         ls -l $DIR/d31f
3633         $LFS getstripe $DIR/d31f/hosts
3634         multiop_bg_pause $DIR/d31f D_c || return 1
3635         MULTIPID=$!
3636
3637         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3638         test_mkdir $DIR/d31f
3639         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3640         cp /etc/hosts $DIR/d31f
3641         ls -l $DIR/d31f
3642         $LFS getstripe $DIR/d31f/hosts
3643         multiop_bg_pause $DIR/d31f D_c || return 1
3644         MULTIPID2=$!
3645
3646         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3647         wait $MULTIPID || error "first opendir $MULTIPID failed"
3648
3649         sleep 6
3650
3651         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3652         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3653         set +vx
3654 }
3655 run_test 31f "remove of open directory with open-unlink file ==="
3656
3657 test_31g() {
3658         echo "-- cross directory link --"
3659         test_mkdir -c1 $DIR/${tdir}ga
3660         test_mkdir -c1 $DIR/${tdir}gb
3661         touch $DIR/${tdir}ga/f
3662         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3663         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3664         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3665         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3666         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3667 }
3668 run_test 31g "cross directory link==============="
3669
3670 test_31h() {
3671         echo "-- cross directory link --"
3672         test_mkdir -c1 $DIR/${tdir}
3673         test_mkdir -c1 $DIR/${tdir}/dir
3674         touch $DIR/${tdir}/f
3675         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3676         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3677         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3678         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3679         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3680 }
3681 run_test 31h "cross directory link under child==============="
3682
3683 test_31i() {
3684         echo "-- cross directory link --"
3685         test_mkdir -c1 $DIR/$tdir
3686         test_mkdir -c1 $DIR/$tdir/dir
3687         touch $DIR/$tdir/dir/f
3688         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3689         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3690         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3691         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3692         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3693 }
3694 run_test 31i "cross directory link under parent==============="
3695
3696 test_31j() {
3697         test_mkdir -c1 -p $DIR/$tdir
3698         test_mkdir -c1 -p $DIR/$tdir/dir1
3699         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3700         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3701         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3702         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3703         return 0
3704 }
3705 run_test 31j "link for directory==============="
3706
3707 test_31k() {
3708         test_mkdir -c1 -p $DIR/$tdir
3709         touch $DIR/$tdir/s
3710         touch $DIR/$tdir/exist
3711         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3712         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3713         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3714         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3715         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3716         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3717         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3718         return 0
3719 }
3720 run_test 31k "link to file: the same, non-existing, dir==============="
3721
3722 test_31m() {
3723         mkdir $DIR/d31m
3724         touch $DIR/d31m/s
3725         mkdir $DIR/d31m2
3726         touch $DIR/d31m2/exist
3727         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3728         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3729         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3730         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3731         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3732         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3733         return 0
3734 }
3735 run_test 31m "link to file: the same, non-existing, dir==============="
3736
3737 test_31n() {
3738         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3739         nlink=$(stat --format=%h $DIR/$tfile)
3740         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3741         local fd=$(free_fd)
3742         local cmd="exec $fd<$DIR/$tfile"
3743         eval $cmd
3744         cmd="exec $fd<&-"
3745         trap "eval $cmd" EXIT
3746         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3747         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3748         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3749         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3750         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3751         eval $cmd
3752 }
3753 run_test 31n "check link count of unlinked file"
3754
3755 link_one() {
3756         local tempfile=$(mktemp $1_XXXXXX)
3757         mlink $tempfile $1 2> /dev/null &&
3758                 echo "$BASHPID: link $tempfile to $1 succeeded"
3759         munlink $tempfile
3760 }
3761
3762 test_31o() { # LU-2901
3763         test_mkdir $DIR/$tdir
3764         for LOOP in $(seq 100); do
3765                 rm -f $DIR/$tdir/$tfile*
3766                 for THREAD in $(seq 8); do
3767                         link_one $DIR/$tdir/$tfile.$LOOP &
3768                 done
3769                 wait
3770                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3771                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3772                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3773                         break || true
3774         done
3775 }
3776 run_test 31o "duplicate hard links with same filename"
3777
3778 test_31p() {
3779         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3780
3781         test_mkdir $DIR/$tdir
3782         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3783         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3784
3785         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3786                 error "open unlink test1 failed"
3787         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3788                 error "open unlink test2 failed"
3789
3790         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3791                 error "test1 still exists"
3792         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3793                 error "test2 still exists"
3794 }
3795 run_test 31p "remove of open striped directory"
3796
3797 test_31q() {
3798         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3799
3800         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3801         index=$($LFS getdirstripe -i $DIR/$tdir)
3802         [ $index -eq 3 ] || error "first stripe index $index != 3"
3803         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3804         [ $index -eq 1 ] || error "second stripe index $index != 1"
3805
3806         # when "-c <stripe_count>" is set, the number of MDTs specified after
3807         # "-i" should equal to the stripe count
3808         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3809 }
3810 run_test 31q "create striped directory on specific MDTs"
3811
3812 #LU-14949
3813 test_31r() {
3814         touch $DIR/$tfile.target
3815         touch $DIR/$tfile.source
3816
3817         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3818         $LCTL set_param fail_loc=0x1419 fail_val=3
3819         cat $DIR/$tfile.target &
3820         CATPID=$!
3821
3822         # Guarantee open is waiting before we get here
3823         sleep 1
3824         mv $DIR/$tfile.source $DIR/$tfile.target
3825
3826         wait $CATPID
3827         RC=$?
3828         if [[ $RC -ne 0 ]]; then
3829                 error "open with cat failed, rc=$RC"
3830         fi
3831 }
3832 run_test 31r "open-rename(replace) race"
3833
3834 cleanup_test32_mount() {
3835         local rc=0
3836         trap 0
3837         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3838         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3839         losetup -d $loopdev || true
3840         rm -rf $DIR/$tdir
3841         return $rc
3842 }
3843
3844 test_32a() {
3845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3846
3847         echo "== more mountpoints and symlinks ================="
3848         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3849         trap cleanup_test32_mount EXIT
3850         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3851         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3852                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3853         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3854                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3855         cleanup_test32_mount
3856 }
3857 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3858
3859 test_32b() {
3860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3861
3862         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3863         trap cleanup_test32_mount EXIT
3864         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3865         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3866                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3867         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3868                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3869         cleanup_test32_mount
3870 }
3871 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3872
3873 test_32c() {
3874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3875
3876         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3877         trap cleanup_test32_mount EXIT
3878         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3879         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3880                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3881         test_mkdir -p $DIR/$tdir/d2/test_dir
3882         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3883                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3884         cleanup_test32_mount
3885 }
3886 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3887
3888 test_32d() {
3889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3890
3891         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3892         trap cleanup_test32_mount EXIT
3893         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3894         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3895                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3896         test_mkdir -p $DIR/$tdir/d2/test_dir
3897         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3898                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3899         cleanup_test32_mount
3900 }
3901 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3902
3903 test_32e() {
3904         rm -fr $DIR/$tdir
3905         test_mkdir -p $DIR/$tdir/tmp
3906         local tmp_dir=$DIR/$tdir/tmp
3907         ln -s $DIR/$tdir $tmp_dir/symlink11
3908         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3909         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3910         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3911 }
3912 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3913
3914 test_32f() {
3915         rm -fr $DIR/$tdir
3916         test_mkdir -p $DIR/$tdir/tmp
3917         local tmp_dir=$DIR/$tdir/tmp
3918         ln -s $DIR/$tdir $tmp_dir/symlink11
3919         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3920         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3921         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3922 }
3923 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3924
3925 test_32g() {
3926         local tmp_dir=$DIR/$tdir/tmp
3927         test_mkdir -p $tmp_dir
3928         test_mkdir $DIR/${tdir}2
3929         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3930         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3931         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3932         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3933         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3934         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3935 }
3936 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3937
3938 test_32h() {
3939         rm -fr $DIR/$tdir $DIR/${tdir}2
3940         tmp_dir=$DIR/$tdir/tmp
3941         test_mkdir -p $tmp_dir
3942         test_mkdir $DIR/${tdir}2
3943         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3944         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3945         ls $tmp_dir/symlink12 || error "listing symlink12"
3946         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3947 }
3948 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3949
3950 test_32i() {
3951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3952
3953         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3954         trap cleanup_test32_mount EXIT
3955         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3956         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3957                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3958         touch $DIR/$tdir/test_file
3959         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3960                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3961         cleanup_test32_mount
3962 }
3963 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3964
3965 test_32j() {
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3969         trap cleanup_test32_mount EXIT
3970         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3971         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3972                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3973         touch $DIR/$tdir/test_file
3974         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3975                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3976         cleanup_test32_mount
3977 }
3978 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3979
3980 test_32k() {
3981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3982
3983         rm -fr $DIR/$tdir
3984         trap cleanup_test32_mount EXIT
3985         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3986         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3987                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3988         test_mkdir -p $DIR/$tdir/d2
3989         touch $DIR/$tdir/d2/test_file || error "touch failed"
3990         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3991                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3992         cleanup_test32_mount
3993 }
3994 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3995
3996 test_32l() {
3997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3998
3999         rm -fr $DIR/$tdir
4000         trap cleanup_test32_mount EXIT
4001         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4002         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4003                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4004         test_mkdir -p $DIR/$tdir/d2
4005         touch $DIR/$tdir/d2/test_file || error "touch failed"
4006         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4007                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4008         cleanup_test32_mount
4009 }
4010 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4011
4012 test_32m() {
4013         rm -fr $DIR/d32m
4014         test_mkdir -p $DIR/d32m/tmp
4015         TMP_DIR=$DIR/d32m/tmp
4016         ln -s $DIR $TMP_DIR/symlink11
4017         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4018         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4019                 error "symlink11 not a link"
4020         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4021                 error "symlink01 not a link"
4022 }
4023 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4024
4025 test_32n() {
4026         rm -fr $DIR/d32n
4027         test_mkdir -p $DIR/d32n/tmp
4028         TMP_DIR=$DIR/d32n/tmp
4029         ln -s $DIR $TMP_DIR/symlink11
4030         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4031         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4032         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4033 }
4034 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4035
4036 test_32o() {
4037         touch $DIR/$tfile
4038         test_mkdir -p $DIR/d32o/tmp
4039         TMP_DIR=$DIR/d32o/tmp
4040         ln -s $DIR/$tfile $TMP_DIR/symlink12
4041         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4042         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4043                 error "symlink12 not a link"
4044         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4045         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4046                 error "$DIR/d32o/tmp/symlink12 not file type"
4047         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4048                 error "$DIR/d32o/symlink02 not file type"
4049 }
4050 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4051
4052 test_32p() {
4053         log 32p_1
4054         rm -fr $DIR/d32p
4055         log 32p_2
4056         rm -f $DIR/$tfile
4057         log 32p_3
4058         touch $DIR/$tfile
4059         log 32p_4
4060         test_mkdir -p $DIR/d32p/tmp
4061         log 32p_5
4062         TMP_DIR=$DIR/d32p/tmp
4063         log 32p_6
4064         ln -s $DIR/$tfile $TMP_DIR/symlink12
4065         log 32p_7
4066         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4067         log 32p_8
4068         cat $DIR/d32p/tmp/symlink12 ||
4069                 error "Can't open $DIR/d32p/tmp/symlink12"
4070         log 32p_9
4071         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4072         log 32p_10
4073 }
4074 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4075
4076 test_32q() {
4077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4078
4079         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4080         trap cleanup_test32_mount EXIT
4081         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4082         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4083         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4084                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4085         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4086         cleanup_test32_mount
4087 }
4088 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4089
4090 test_32r() {
4091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4092
4093         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4094         trap cleanup_test32_mount EXIT
4095         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4096         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4097         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4098                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4099         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4100         cleanup_test32_mount
4101 }
4102 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4103
4104 test_33aa() {
4105         rm -f $DIR/$tfile
4106         touch $DIR/$tfile
4107         chmod 444 $DIR/$tfile
4108         chown $RUNAS_ID $DIR/$tfile
4109         log 33_1
4110         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4111         log 33_2
4112 }
4113 run_test 33aa "write file with mode 444 (should return error)"
4114
4115 test_33a() {
4116         rm -fr $DIR/$tdir
4117         test_mkdir $DIR/$tdir
4118         chown $RUNAS_ID $DIR/$tdir
4119         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4120                 error "$RUNAS create $tdir/$tfile failed"
4121         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4122                 error "open RDWR" || true
4123 }
4124 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4125
4126 test_33b() {
4127         rm -fr $DIR/$tdir
4128         test_mkdir $DIR/$tdir
4129         chown $RUNAS_ID $DIR/$tdir
4130         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4131 }
4132 run_test 33b "test open file with malformed flags (No panic)"
4133
4134 test_33c() {
4135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4136         remote_ost_nodsh && skip "remote OST with nodsh"
4137
4138         local ostnum
4139         local ostname
4140         local write_bytes
4141         local all_zeros
4142
4143         all_zeros=true
4144         test_mkdir $DIR/$tdir
4145         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4146
4147         sync
4148         for ostnum in $(seq $OSTCOUNT); do
4149                 # test-framework's OST numbering is one-based, while Lustre's
4150                 # is zero-based
4151                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4152                 # check if at least some write_bytes stats are counted
4153                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4154                               obdfilter.$ostname.stats |
4155                               awk '/^write_bytes/ {print $7}' )
4156                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4157                 if (( ${write_bytes:-0} > 0 )); then
4158                         all_zeros=false
4159                         break
4160                 fi
4161         done
4162
4163         $all_zeros || return 0
4164
4165         # Write four bytes
4166         echo foo > $DIR/$tdir/bar
4167         # Really write them
4168         sync
4169
4170         # Total up write_bytes after writing.  We'd better find non-zeros.
4171         for ostnum in $(seq $OSTCOUNT); do
4172                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4173                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4174                               obdfilter/$ostname/stats |
4175                               awk '/^write_bytes/ {print $7}' )
4176                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4177                 if (( ${write_bytes:-0} > 0 )); then
4178                         all_zeros=false
4179                         break
4180                 fi
4181         done
4182
4183         if $all_zeros; then
4184                 for ostnum in $(seq $OSTCOUNT); do
4185                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4186                         echo "Check write_bytes is in obdfilter.*.stats:"
4187                         do_facet ost$ostnum lctl get_param -n \
4188                                 obdfilter.$ostname.stats
4189                 done
4190                 error "OST not keeping write_bytes stats (b=22312)"
4191         fi
4192 }
4193 run_test 33c "test write_bytes stats"
4194
4195 test_33d() {
4196         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4198
4199         local MDTIDX=1
4200         local remote_dir=$DIR/$tdir/remote_dir
4201
4202         test_mkdir $DIR/$tdir
4203         $LFS mkdir -i $MDTIDX $remote_dir ||
4204                 error "create remote directory failed"
4205
4206         touch $remote_dir/$tfile
4207         chmod 444 $remote_dir/$tfile
4208         chown $RUNAS_ID $remote_dir/$tfile
4209
4210         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4211
4212         chown $RUNAS_ID $remote_dir
4213         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4214                                         error "create" || true
4215         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4216                                     error "open RDWR" || true
4217         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4218 }
4219 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4220
4221 test_33e() {
4222         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4223
4224         mkdir $DIR/$tdir
4225
4226         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4227         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4228         mkdir $DIR/$tdir/local_dir
4229
4230         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4231         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4232         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4233
4234         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4235                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4236
4237         rmdir $DIR/$tdir/* || error "rmdir failed"
4238
4239         umask 777
4240         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4241         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4242         mkdir $DIR/$tdir/local_dir
4243
4244         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4245         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4246         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4247
4248         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4249                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4250
4251         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4252
4253         umask 000
4254         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4255         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4256         mkdir $DIR/$tdir/local_dir
4257
4258         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4259         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4260         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4261
4262         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4263                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4264 }
4265 run_test 33e "mkdir and striped directory should have same mode"
4266
4267 cleanup_33f() {
4268         trap 0
4269         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4270 }
4271
4272 test_33f() {
4273         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4274         remote_mds_nodsh && skip "remote MDS with nodsh"
4275
4276         mkdir $DIR/$tdir
4277         chmod go+rwx $DIR/$tdir
4278         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4279         trap cleanup_33f EXIT
4280
4281         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4282                 error "cannot create striped directory"
4283
4284         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4285                 error "cannot create files in striped directory"
4286
4287         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4288                 error "cannot remove files in striped directory"
4289
4290         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4291                 error "cannot remove striped directory"
4292
4293         cleanup_33f
4294 }
4295 run_test 33f "nonroot user can create, access, and remove a striped directory"
4296
4297 test_33g() {
4298         mkdir -p $DIR/$tdir/dir2
4299
4300         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4301         echo $err
4302         [[ $err =~ "exists" ]] || error "Not exists error"
4303 }
4304 run_test 33g "nonroot user create already existing root created file"
4305
4306 sub_33h() {
4307         local hash_type=$1
4308         local count=250
4309
4310         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4311                 error "lfs mkdir -H $hash_type $tdir failed"
4312         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4313
4314         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4315         local index2
4316         local fname
4317
4318         for fname in $DIR/$tdir/$tfile.bak \
4319                      $DIR/$tdir/$tfile.SAV \
4320                      $DIR/$tdir/$tfile.orig \
4321                      $DIR/$tdir/$tfile~; do
4322                 touch $fname || error "touch $fname failed"
4323                 index2=$($LFS getstripe -m $fname)
4324                 (( $index == $index2 )) ||
4325                         error "$fname MDT index mismatch $index != $index2"
4326         done
4327
4328         local failed=0
4329         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4330         local pattern
4331
4332         for pattern in ${patterns[*]}; do
4333                 echo "pattern $pattern"
4334                 fname=$DIR/$tdir/$pattern
4335                 for (( i = 0; i < $count; i++ )); do
4336                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4337                                 error "mktemp $DIR/$tdir/$pattern failed"
4338                         index2=$($LFS getstripe -m $fname)
4339                         (( $index == $index2 )) && continue
4340
4341                         failed=$((failed + 1))
4342                         echo "$fname MDT index mismatch $index != $index2"
4343                 done
4344         done
4345
4346         echo "$failed/$count MDT index mismatches, expect ~2-4"
4347         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4348
4349         local same=0
4350         local expect
4351
4352         # verify that "crush" is still broken with all files on same MDT,
4353         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4354         [[ "$hash_type" == "crush" ]] && expect=$count ||
4355                 expect=$((count / MDSCOUNT))
4356
4357         # crush2 doesn't put all-numeric suffixes on the same MDT,
4358         # filename like $tfile.12345678 should *not* be considered temp
4359         for pattern in ${patterns[*]}; do
4360                 local base=${pattern%%X*}
4361                 local suff=${pattern#$base}
4362
4363                 echo "pattern $pattern"
4364                 for (( i = 0; i < $count; i++ )); do
4365                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4366                         touch $fname || error "touch $fname failed"
4367                         index2=$($LFS getstripe -m $fname)
4368                         (( $index != $index2 )) && continue
4369
4370                         same=$((same + 1))
4371                 done
4372         done
4373
4374         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4375         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4376            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4377                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4378         same=0
4379
4380         # crush2 doesn't put suffixes with special characters on the same MDT
4381         # filename like $tfile.txt.1234 should *not* be considered temp
4382         for pattern in ${patterns[*]}; do
4383                 local base=${pattern%%X*}
4384                 local suff=${pattern#$base}
4385
4386                 pattern=$base...${suff/XXX}
4387                 echo "pattern=$pattern"
4388                 for (( i = 0; i < $count; i++ )); do
4389                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4390                                 error "touch $fname failed"
4391                         index2=$($LFS getstripe -m $fname)
4392                         (( $index != $index2 )) && continue
4393
4394                         same=$((same + 1))
4395                 done
4396         done
4397
4398         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4399         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4400            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4401                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4402 }
4403
4404 test_33h() {
4405         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4406         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4407                 skip "Need MDS version at least 2.13.50"
4408
4409         sub_33h crush
4410 }
4411 run_test 33h "temp file is located on the same MDT as target (crush)"
4412
4413 test_33hh() {
4414         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4415         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4416         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4417                 skip "Need MDS version at least 2.15.0 for crush2"
4418
4419         sub_33h crush2
4420 }
4421 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4422
4423 test_33i()
4424 {
4425         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4426
4427         local FNAME=$(str_repeat 'f' 250)
4428
4429         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4430         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4431
4432         local count
4433         local total
4434
4435         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4436
4437         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4438
4439         lctl --device %$MDC deactivate
4440         stack_trap "lctl --device %$MDC activate"
4441         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4442         total=$(\ls -l $DIR/$tdir | wc -l)
4443         # "ls -l" will list total in the first line
4444         total=$((total - 1))
4445         (( total + count == 1000 )) ||
4446                 error "ls list $total files, $count files on MDT1"
4447 }
4448 run_test 33i "striped directory can be accessed when one MDT is down"
4449
4450 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4451 test_34a() {
4452         rm -f $DIR/f34
4453         $MCREATE $DIR/f34 || error "mcreate failed"
4454         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4455                 error "getstripe failed"
4456         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4457         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4458                 error "getstripe failed"
4459         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4460                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4461 }
4462 run_test 34a "truncate file that has not been opened ==========="
4463
4464 test_34b() {
4465         [ ! -f $DIR/f34 ] && test_34a
4466         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4467                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4468         $OPENFILE -f O_RDONLY $DIR/f34
4469         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4470                 error "getstripe failed"
4471         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4472                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4473 }
4474 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4475
4476 test_34c() {
4477         [ ! -f $DIR/f34 ] && test_34a
4478         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4479                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4480         $OPENFILE -f O_RDWR $DIR/f34
4481         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4482                 error "$LFS getstripe failed"
4483         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4484                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4485 }
4486 run_test 34c "O_RDWR opening file-with-size works =============="
4487
4488 test_34d() {
4489         [ ! -f $DIR/f34 ] && test_34a
4490         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4491                 error "dd failed"
4492         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4493                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4494         rm $DIR/f34
4495 }
4496 run_test 34d "write to sparse file ============================="
4497
4498 test_34e() {
4499         rm -f $DIR/f34e
4500         $MCREATE $DIR/f34e || error "mcreate failed"
4501         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4502         $CHECKSTAT -s 1000 $DIR/f34e ||
4503                 error "Size of $DIR/f34e not equal to 1000 bytes"
4504         $OPENFILE -f O_RDWR $DIR/f34e
4505         $CHECKSTAT -s 1000 $DIR/f34e ||
4506                 error "Size of $DIR/f34e not equal to 1000 bytes"
4507 }
4508 run_test 34e "create objects, some with size and some without =="
4509
4510 test_34f() { # bug 6242, 6243
4511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4512
4513         SIZE34F=48000
4514         rm -f $DIR/f34f
4515         $MCREATE $DIR/f34f || error "mcreate failed"
4516         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4517         dd if=$DIR/f34f of=$TMP/f34f
4518         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4519         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4520         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4521         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4522         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4523 }
4524 run_test 34f "read from a file with no objects until EOF ======="
4525
4526 test_34g() {
4527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4528
4529         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4530                 error "dd failed"
4531         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4532         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4533                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4534         cancel_lru_locks osc
4535         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4536                 error "wrong size after lock cancel"
4537
4538         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4539         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4540                 error "expanding truncate failed"
4541         cancel_lru_locks osc
4542         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4543                 error "wrong expanded size after lock cancel"
4544 }
4545 run_test 34g "truncate long file ==============================="
4546
4547 test_34h() {
4548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4549
4550         local gid=10
4551         local sz=1000
4552
4553         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4554         sync # Flush the cache so that multiop below does not block on cache
4555              # flush when getting the group lock
4556         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4557         MULTIPID=$!
4558
4559         # Since just timed wait is not good enough, let's do a sync write
4560         # that way we are sure enough time for a roundtrip + processing
4561         # passed + 2 seconds of extra margin.
4562         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4563         rm $DIR/${tfile}-1
4564         sleep 2
4565
4566         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4567                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4568                 kill -9 $MULTIPID
4569         fi
4570         wait $MULTIPID
4571         local nsz=`stat -c %s $DIR/$tfile`
4572         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4573 }
4574 run_test 34h "ftruncate file under grouplock should not block"
4575
4576 test_35a() {
4577         cp /bin/sh $DIR/f35a
4578         chmod 444 $DIR/f35a
4579         chown $RUNAS_ID $DIR/f35a
4580         $RUNAS $DIR/f35a && error || true
4581         rm $DIR/f35a
4582 }
4583 run_test 35a "exec file with mode 444 (should return and not leak)"
4584
4585 test_36a() {
4586         rm -f $DIR/f36
4587         utime $DIR/f36 || error "utime failed for MDS"
4588 }
4589 run_test 36a "MDS utime check (mknod, utime)"
4590
4591 test_36b() {
4592         echo "" > $DIR/f36
4593         utime $DIR/f36 || error "utime failed for OST"
4594 }
4595 run_test 36b "OST utime check (open, utime)"
4596
4597 test_36c() {
4598         rm -f $DIR/d36/f36
4599         test_mkdir $DIR/d36
4600         chown $RUNAS_ID $DIR/d36
4601         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4602 }
4603 run_test 36c "non-root MDS utime check (mknod, utime)"
4604
4605 test_36d() {
4606         [ ! -d $DIR/d36 ] && test_36c
4607         echo "" > $DIR/d36/f36
4608         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4609 }
4610 run_test 36d "non-root OST utime check (open, utime)"
4611
4612 test_36e() {
4613         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4614
4615         test_mkdir $DIR/$tdir
4616         touch $DIR/$tdir/$tfile
4617         $RUNAS utime $DIR/$tdir/$tfile &&
4618                 error "utime worked, expected failure" || true
4619 }
4620 run_test 36e "utime on non-owned file (should return error)"
4621
4622 subr_36fh() {
4623         local fl="$1"
4624         local LANG_SAVE=$LANG
4625         local LC_LANG_SAVE=$LC_LANG
4626         export LANG=C LC_LANG=C # for date language
4627
4628         DATESTR="Dec 20  2000"
4629         test_mkdir $DIR/$tdir
4630         lctl set_param fail_loc=$fl
4631         date; date +%s
4632         cp /etc/hosts $DIR/$tdir/$tfile
4633         sync & # write RPC generated with "current" inode timestamp, but delayed
4634         sleep 1
4635         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4636         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4637         cancel_lru_locks $OSC
4638         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4639         date; date +%s
4640         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4641                 echo "BEFORE: $LS_BEFORE" && \
4642                 echo "AFTER : $LS_AFTER" && \
4643                 echo "WANT  : $DATESTR" && \
4644                 error "$DIR/$tdir/$tfile timestamps changed" || true
4645
4646         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4647 }
4648
4649 test_36f() {
4650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4651
4652         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4653         subr_36fh "0x80000214"
4654 }
4655 run_test 36f "utime on file racing with OST BRW write =========="
4656
4657 test_36g() {
4658         remote_ost_nodsh && skip "remote OST with nodsh"
4659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4660         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4661                 skip "Need MDS version at least 2.12.51"
4662
4663         local fmd_max_age
4664         local fmd
4665         local facet="ost1"
4666         local tgt="obdfilter"
4667
4668         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4669
4670         test_mkdir $DIR/$tdir
4671         fmd_max_age=$(do_facet $facet \
4672                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4673                 head -n 1")
4674
4675         echo "FMD max age: ${fmd_max_age}s"
4676         touch $DIR/$tdir/$tfile
4677         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4678                 gawk '{cnt=cnt+$1}  END{print cnt}')
4679         echo "FMD before: $fmd"
4680         [[ $fmd == 0 ]] &&
4681                 error "FMD wasn't create by touch"
4682         sleep $((fmd_max_age + 12))
4683         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4684                 gawk '{cnt=cnt+$1}  END{print cnt}')
4685         echo "FMD after: $fmd"
4686         [[ $fmd == 0 ]] ||
4687                 error "FMD wasn't expired by ping"
4688 }
4689 run_test 36g "FMD cache expiry ====================="
4690
4691 test_36h() {
4692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4693
4694         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4695         subr_36fh "0x80000227"
4696 }
4697 run_test 36h "utime on file racing with OST BRW write =========="
4698
4699 test_36i() {
4700         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4701
4702         test_mkdir $DIR/$tdir
4703         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4704
4705         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4706         local new_mtime=$((mtime + 200))
4707
4708         #change Modify time of striped dir
4709         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4710                         error "change mtime failed"
4711
4712         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4713
4714         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4715 }
4716 run_test 36i "change mtime on striped directory"
4717
4718 # test_37 - duplicate with tests 32q 32r
4719
4720 test_38() {
4721         local file=$DIR/$tfile
4722         touch $file
4723         openfile -f O_DIRECTORY $file
4724         local RC=$?
4725         local ENOTDIR=20
4726         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4727         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4728 }
4729 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4730
4731 test_39a() { # was test_39
4732         touch $DIR/$tfile
4733         touch $DIR/${tfile}2
4734 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4735 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4736 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4737         sleep 2
4738         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4739         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4740                 echo "mtime"
4741                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4742                 echo "atime"
4743                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4744                 echo "ctime"
4745                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4746                 error "O_TRUNC didn't change timestamps"
4747         fi
4748 }
4749 run_test 39a "mtime changed on create"
4750
4751 test_39b() {
4752         test_mkdir -c1 $DIR/$tdir
4753         cp -p /etc/passwd $DIR/$tdir/fopen
4754         cp -p /etc/passwd $DIR/$tdir/flink
4755         cp -p /etc/passwd $DIR/$tdir/funlink
4756         cp -p /etc/passwd $DIR/$tdir/frename
4757         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4758
4759         sleep 1
4760         echo "aaaaaa" >> $DIR/$tdir/fopen
4761         echo "aaaaaa" >> $DIR/$tdir/flink
4762         echo "aaaaaa" >> $DIR/$tdir/funlink
4763         echo "aaaaaa" >> $DIR/$tdir/frename
4764
4765         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4766         local link_new=`stat -c %Y $DIR/$tdir/flink`
4767         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4768         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4769
4770         cat $DIR/$tdir/fopen > /dev/null
4771         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4772         rm -f $DIR/$tdir/funlink2
4773         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4774
4775         for (( i=0; i < 2; i++ )) ; do
4776                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4777                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4778                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4779                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4780
4781                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4782                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4783                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4784                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4785
4786                 cancel_lru_locks $OSC
4787                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4788         done
4789 }
4790 run_test 39b "mtime change on open, link, unlink, rename  ======"
4791
4792 # this should be set to past
4793 TEST_39_MTIME=`date -d "1 year ago" +%s`
4794
4795 # bug 11063
4796 test_39c() {
4797         touch $DIR1/$tfile
4798         sleep 2
4799         local mtime0=`stat -c %Y $DIR1/$tfile`
4800
4801         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4802         local mtime1=`stat -c %Y $DIR1/$tfile`
4803         [ "$mtime1" = $TEST_39_MTIME ] || \
4804                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4805
4806         local d1=`date +%s`
4807         echo hello >> $DIR1/$tfile
4808         local d2=`date +%s`
4809         local mtime2=`stat -c %Y $DIR1/$tfile`
4810         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4811                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4812
4813         mv $DIR1/$tfile $DIR1/$tfile-1
4814
4815         for (( i=0; i < 2; i++ )) ; do
4816                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4817                 [ "$mtime2" = "$mtime3" ] || \
4818                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4819
4820                 cancel_lru_locks $OSC
4821                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4822         done
4823 }
4824 run_test 39c "mtime change on rename ==========================="
4825
4826 # bug 21114
4827 test_39d() {
4828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4829
4830         touch $DIR1/$tfile
4831         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4832
4833         for (( i=0; i < 2; i++ )) ; do
4834                 local mtime=`stat -c %Y $DIR1/$tfile`
4835                 [ $mtime = $TEST_39_MTIME ] || \
4836                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4837
4838                 cancel_lru_locks $OSC
4839                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4840         done
4841 }
4842 run_test 39d "create, utime, stat =============================="
4843
4844 # bug 21114
4845 test_39e() {
4846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4847
4848         touch $DIR1/$tfile
4849         local mtime1=`stat -c %Y $DIR1/$tfile`
4850
4851         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4852
4853         for (( i=0; i < 2; i++ )) ; do
4854                 local mtime2=`stat -c %Y $DIR1/$tfile`
4855                 [ $mtime2 = $TEST_39_MTIME ] || \
4856                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4857
4858                 cancel_lru_locks $OSC
4859                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4860         done
4861 }
4862 run_test 39e "create, stat, utime, stat ========================"
4863
4864 # bug 21114
4865 test_39f() {
4866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4867
4868         touch $DIR1/$tfile
4869         mtime1=`stat -c %Y $DIR1/$tfile`
4870
4871         sleep 2
4872         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4873
4874         for (( i=0; i < 2; i++ )) ; do
4875                 local mtime2=`stat -c %Y $DIR1/$tfile`
4876                 [ $mtime2 = $TEST_39_MTIME ] || \
4877                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4878
4879                 cancel_lru_locks $OSC
4880                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4881         done
4882 }
4883 run_test 39f "create, stat, sleep, utime, stat ================="
4884
4885 # bug 11063
4886 test_39g() {
4887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4888
4889         echo hello >> $DIR1/$tfile
4890         local mtime1=`stat -c %Y $DIR1/$tfile`
4891
4892         sleep 2
4893         chmod o+r $DIR1/$tfile
4894
4895         for (( i=0; i < 2; i++ )) ; do
4896                 local mtime2=`stat -c %Y $DIR1/$tfile`
4897                 [ "$mtime1" = "$mtime2" ] || \
4898                         error "lost mtime: $mtime2, should be $mtime1"
4899
4900                 cancel_lru_locks $OSC
4901                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4902         done
4903 }
4904 run_test 39g "write, chmod, stat ==============================="
4905
4906 # bug 11063
4907 test_39h() {
4908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4909
4910         touch $DIR1/$tfile
4911         sleep 1
4912
4913         local d1=`date`
4914         echo hello >> $DIR1/$tfile
4915         local mtime1=`stat -c %Y $DIR1/$tfile`
4916
4917         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4918         local d2=`date`
4919         if [ "$d1" != "$d2" ]; then
4920                 echo "write and touch not within one second"
4921         else
4922                 for (( i=0; i < 2; i++ )) ; do
4923                         local mtime2=`stat -c %Y $DIR1/$tfile`
4924                         [ "$mtime2" = $TEST_39_MTIME ] || \
4925                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4926
4927                         cancel_lru_locks $OSC
4928                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4929                 done
4930         fi
4931 }
4932 run_test 39h "write, utime within one second, stat ============="
4933
4934 test_39i() {
4935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4936
4937         touch $DIR1/$tfile
4938         sleep 1
4939
4940         echo hello >> $DIR1/$tfile
4941         local mtime1=`stat -c %Y $DIR1/$tfile`
4942
4943         mv $DIR1/$tfile $DIR1/$tfile-1
4944
4945         for (( i=0; i < 2; i++ )) ; do
4946                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4947
4948                 [ "$mtime1" = "$mtime2" ] || \
4949                         error "lost mtime: $mtime2, should be $mtime1"
4950
4951                 cancel_lru_locks $OSC
4952                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4953         done
4954 }
4955 run_test 39i "write, rename, stat =============================="
4956
4957 test_39j() {
4958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4959
4960         start_full_debug_logging
4961         touch $DIR1/$tfile
4962         sleep 1
4963
4964         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4965         lctl set_param fail_loc=0x80000412
4966         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4967                 error "multiop failed"
4968         local multipid=$!
4969         local mtime1=`stat -c %Y $DIR1/$tfile`
4970
4971         mv $DIR1/$tfile $DIR1/$tfile-1
4972
4973         kill -USR1 $multipid
4974         wait $multipid || error "multiop close failed"
4975
4976         for (( i=0; i < 2; i++ )) ; do
4977                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4978                 [ "$mtime1" = "$mtime2" ] ||
4979                         error "mtime is lost on close: $mtime2, " \
4980                               "should be $mtime1"
4981
4982                 cancel_lru_locks
4983                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4984         done
4985         lctl set_param fail_loc=0
4986         stop_full_debug_logging
4987 }
4988 run_test 39j "write, rename, close, stat ======================="
4989
4990 test_39k() {
4991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4992
4993         touch $DIR1/$tfile
4994         sleep 1
4995
4996         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4997         local multipid=$!
4998         local mtime1=`stat -c %Y $DIR1/$tfile`
4999
5000         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5001
5002         kill -USR1 $multipid
5003         wait $multipid || error "multiop close failed"
5004
5005         for (( i=0; i < 2; i++ )) ; do
5006                 local mtime2=`stat -c %Y $DIR1/$tfile`
5007
5008                 [ "$mtime2" = $TEST_39_MTIME ] || \
5009                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5010
5011                 cancel_lru_locks
5012                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5013         done
5014 }
5015 run_test 39k "write, utime, close, stat ========================"
5016
5017 # this should be set to future
5018 TEST_39_ATIME=`date -d "1 year" +%s`
5019
5020 test_39l() {
5021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5022         remote_mds_nodsh && skip "remote MDS with nodsh"
5023
5024         local atime_diff=$(do_facet $SINGLEMDS \
5025                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5026         rm -rf $DIR/$tdir
5027         mkdir_on_mdt0 $DIR/$tdir
5028
5029         # test setting directory atime to future
5030         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5031         local atime=$(stat -c %X $DIR/$tdir)
5032         [ "$atime" = $TEST_39_ATIME ] ||
5033                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5034
5035         # test setting directory atime from future to now
5036         local now=$(date +%s)
5037         touch -a -d @$now $DIR/$tdir
5038
5039         atime=$(stat -c %X $DIR/$tdir)
5040         [ "$atime" -eq "$now"  ] ||
5041                 error "atime is not updated from future: $atime, $now"
5042
5043         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5044         sleep 3
5045
5046         # test setting directory atime when now > dir atime + atime_diff
5047         local d1=$(date +%s)
5048         ls $DIR/$tdir
5049         local d2=$(date +%s)
5050         cancel_lru_locks mdc
5051         atime=$(stat -c %X $DIR/$tdir)
5052         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5053                 error "atime is not updated  : $atime, should be $d2"
5054
5055         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5056         sleep 3
5057
5058         # test not setting directory atime when now < dir atime + atime_diff
5059         ls $DIR/$tdir
5060         cancel_lru_locks mdc
5061         atime=$(stat -c %X $DIR/$tdir)
5062         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5063                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5064
5065         do_facet $SINGLEMDS \
5066                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5067 }
5068 run_test 39l "directory atime update ==========================="
5069
5070 test_39m() {
5071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5072
5073         touch $DIR1/$tfile
5074         sleep 2
5075         local far_past_mtime=$(date -d "May 29 1953" +%s)
5076         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5077
5078         touch -m -d @$far_past_mtime $DIR1/$tfile
5079         touch -a -d @$far_past_atime $DIR1/$tfile
5080
5081         for (( i=0; i < 2; i++ )) ; do
5082                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5083                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5084                         error "atime or mtime set incorrectly"
5085
5086                 cancel_lru_locks $OSC
5087                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5088         done
5089 }
5090 run_test 39m "test atime and mtime before 1970"
5091
5092 test_39n() { # LU-3832
5093         remote_mds_nodsh && skip "remote MDS with nodsh"
5094
5095         local atime_diff=$(do_facet $SINGLEMDS \
5096                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5097         local atime0
5098         local atime1
5099         local atime2
5100
5101         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5102
5103         rm -rf $DIR/$tfile
5104         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5105         atime0=$(stat -c %X $DIR/$tfile)
5106
5107         sleep 5
5108         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5109         atime1=$(stat -c %X $DIR/$tfile)
5110
5111         sleep 5
5112         cancel_lru_locks mdc
5113         cancel_lru_locks osc
5114         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5115         atime2=$(stat -c %X $DIR/$tfile)
5116
5117         do_facet $SINGLEMDS \
5118                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5119
5120         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5121         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5122 }
5123 run_test 39n "check that O_NOATIME is honored"
5124
5125 test_39o() {
5126         TESTDIR=$DIR/$tdir/$tfile
5127         [ -e $TESTDIR ] && rm -rf $TESTDIR
5128         mkdir -p $TESTDIR
5129         cd $TESTDIR
5130         links1=2
5131         ls
5132         mkdir a b
5133         ls
5134         links2=$(stat -c %h .)
5135         [ $(($links1 + 2)) != $links2 ] &&
5136                 error "wrong links count $(($links1 + 2)) != $links2"
5137         rmdir b
5138         links3=$(stat -c %h .)
5139         [ $(($links1 + 1)) != $links3 ] &&
5140                 error "wrong links count $links1 != $links3"
5141         return 0
5142 }
5143 run_test 39o "directory cached attributes updated after create"
5144
5145 test_39p() {
5146         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5147
5148         local MDTIDX=1
5149         TESTDIR=$DIR/$tdir/$tdir
5150         [ -e $TESTDIR ] && rm -rf $TESTDIR
5151         test_mkdir -p $TESTDIR
5152         cd $TESTDIR
5153         links1=2
5154         ls
5155         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5156         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5157         ls
5158         links2=$(stat -c %h .)
5159         [ $(($links1 + 2)) != $links2 ] &&
5160                 error "wrong links count $(($links1 + 2)) != $links2"
5161         rmdir remote_dir2
5162         links3=$(stat -c %h .)
5163         [ $(($links1 + 1)) != $links3 ] &&
5164                 error "wrong links count $links1 != $links3"
5165         return 0
5166 }
5167 run_test 39p "remote directory cached attributes updated after create ========"
5168
5169 test_39r() {
5170         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5171                 skip "no atime update on old OST"
5172         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5173                 skip_env "ldiskfs only test"
5174         fi
5175
5176         local saved_adiff
5177         saved_adiff=$(do_facet ost1 \
5178                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5179         stack_trap "do_facet ost1 \
5180                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5181
5182         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5183
5184         $LFS setstripe -i 0 $DIR/$tfile
5185         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5186                 error "can't write initial file"
5187         cancel_lru_locks osc
5188
5189         # exceed atime_diff and access file
5190         sleep 10
5191         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5192                 error "can't udpate atime"
5193
5194         local atime_cli=$(stat -c %X $DIR/$tfile)
5195         echo "client atime: $atime_cli"
5196         # allow atime update to be written to device
5197         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5198         sleep 5
5199
5200         local ostdev=$(ostdevname 1)
5201         local fid=($(lfs getstripe -y $DIR/$tfile |
5202                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5203         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5204         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5205
5206         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5207         local atime_ost=$(do_facet ost1 "$cmd" |&
5208                           awk -F'[: ]' '/atime:/ { print $4 }')
5209         (( atime_cli == atime_ost )) ||
5210                 error "atime on client $atime_cli != ost $atime_ost"
5211 }
5212 run_test 39r "lazy atime update on OST"
5213
5214 test_39q() { # LU-8041
5215         local testdir=$DIR/$tdir
5216         mkdir -p $testdir
5217         multiop_bg_pause $testdir D_c || error "multiop failed"
5218         local multipid=$!
5219         cancel_lru_locks mdc
5220         kill -USR1 $multipid
5221         local atime=$(stat -c %X $testdir)
5222         [ "$atime" -ne 0 ] || error "atime is zero"
5223 }
5224 run_test 39q "close won't zero out atime"
5225
5226 test_40() {
5227         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5228         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5229                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5230         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5231                 error "$tfile is not 4096 bytes in size"
5232 }
5233 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5234
5235 test_41() {
5236         # bug 1553
5237         small_write $DIR/f41 18
5238 }
5239 run_test 41 "test small file write + fstat ====================="
5240
5241 count_ost_writes() {
5242         lctl get_param -n ${OSC}.*.stats |
5243                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5244                         END { printf("%0.0f", writes) }'
5245 }
5246
5247 # decent default
5248 WRITEBACK_SAVE=500
5249 DIRTY_RATIO_SAVE=40
5250 MAX_DIRTY_RATIO=50
5251 BG_DIRTY_RATIO_SAVE=10
5252 MAX_BG_DIRTY_RATIO=25
5253
5254 start_writeback() {
5255         trap 0
5256         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5257         # dirty_ratio, dirty_background_ratio
5258         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5259                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5260                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5261                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5262         else
5263                 # if file not here, we are a 2.4 kernel
5264                 kill -CONT `pidof kupdated`
5265         fi
5266 }
5267
5268 stop_writeback() {
5269         # setup the trap first, so someone cannot exit the test at the
5270         # exact wrong time and mess up a machine
5271         trap start_writeback EXIT
5272         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5273         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5274                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5275                 sysctl -w vm.dirty_writeback_centisecs=0
5276                 sysctl -w vm.dirty_writeback_centisecs=0
5277                 # save and increase /proc/sys/vm/dirty_ratio
5278                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5279                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5280                 # save and increase /proc/sys/vm/dirty_background_ratio
5281                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5282                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5283         else
5284                 # if file not here, we are a 2.4 kernel
5285                 kill -STOP `pidof kupdated`
5286         fi
5287 }
5288
5289 # ensure that all stripes have some grant before we test client-side cache
5290 setup_test42() {
5291         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5292                 dd if=/dev/zero of=$i bs=4k count=1
5293                 rm $i
5294         done
5295 }
5296
5297 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5298 # file truncation, and file removal.
5299 test_42a() {
5300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5301
5302         setup_test42
5303         cancel_lru_locks $OSC
5304         stop_writeback
5305         sync; sleep 1; sync # just to be safe
5306         BEFOREWRITES=`count_ost_writes`
5307         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5308         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5309         AFTERWRITES=`count_ost_writes`
5310         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5311                 error "$BEFOREWRITES < $AFTERWRITES"
5312         start_writeback
5313 }
5314 run_test 42a "ensure that we don't flush on close"
5315
5316 test_42b() {
5317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5318
5319         setup_test42
5320         cancel_lru_locks $OSC
5321         stop_writeback
5322         sync
5323         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5324         BEFOREWRITES=$(count_ost_writes)
5325         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5326         AFTERWRITES=$(count_ost_writes)
5327         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5328                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5329         fi
5330         BEFOREWRITES=$(count_ost_writes)
5331         sync || error "sync: $?"
5332         AFTERWRITES=$(count_ost_writes)
5333         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5334                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5335         fi
5336         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5337         start_writeback
5338         return 0
5339 }
5340 run_test 42b "test destroy of file with cached dirty data ======"
5341
5342 # if these tests just want to test the effect of truncation,
5343 # they have to be very careful.  consider:
5344 # - the first open gets a {0,EOF}PR lock
5345 # - the first write conflicts and gets a {0, count-1}PW
5346 # - the rest of the writes are under {count,EOF}PW
5347 # - the open for truncate tries to match a {0,EOF}PR
5348 #   for the filesize and cancels the PWs.
5349 # any number of fixes (don't get {0,EOF} on open, match
5350 # composite locks, do smarter file size management) fix
5351 # this, but for now we want these tests to verify that
5352 # the cancellation with truncate intent works, so we
5353 # start the file with a full-file pw lock to match against
5354 # until the truncate.
5355 trunc_test() {
5356         test=$1
5357         file=$DIR/$test
5358         offset=$2
5359         cancel_lru_locks $OSC
5360         stop_writeback
5361         # prime the file with 0,EOF PW to match
5362         touch $file
5363         $TRUNCATE $file 0
5364         sync; sync
5365         # now the real test..
5366         dd if=/dev/zero of=$file bs=1024 count=100
5367         BEFOREWRITES=`count_ost_writes`
5368         $TRUNCATE $file $offset
5369         cancel_lru_locks $OSC
5370         AFTERWRITES=`count_ost_writes`
5371         start_writeback
5372 }
5373
5374 test_42c() {
5375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5376
5377         trunc_test 42c 1024
5378         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5379                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5380         rm $file
5381 }
5382 run_test 42c "test partial truncate of file with cached dirty data"
5383
5384 test_42d() {
5385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5386
5387         trunc_test 42d 0
5388         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5389                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5390         rm $file
5391 }
5392 run_test 42d "test complete truncate of file with cached dirty data"
5393
5394 test_42e() { # bug22074
5395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5396
5397         local TDIR=$DIR/${tdir}e
5398         local pages=16 # hardcoded 16 pages, don't change it.
5399         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5400         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5401         local max_dirty_mb
5402         local warmup_files
5403
5404         test_mkdir $DIR/${tdir}e
5405         $LFS setstripe -c 1 $TDIR
5406         createmany -o $TDIR/f $files
5407
5408         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5409
5410         # we assume that with $OSTCOUNT files, at least one of them will
5411         # be allocated on OST0.
5412         warmup_files=$((OSTCOUNT * max_dirty_mb))
5413         createmany -o $TDIR/w $warmup_files
5414
5415         # write a large amount of data into one file and sync, to get good
5416         # avail_grant number from OST.
5417         for ((i=0; i<$warmup_files; i++)); do
5418                 idx=$($LFS getstripe -i $TDIR/w$i)
5419                 [ $idx -ne 0 ] && continue
5420                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5421                 break
5422         done
5423         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5424         sync
5425         $LCTL get_param $proc_osc0/cur_dirty_bytes
5426         $LCTL get_param $proc_osc0/cur_grant_bytes
5427
5428         # create as much dirty pages as we can while not to trigger the actual
5429         # RPCs directly. but depends on the env, VFS may trigger flush during this
5430         # period, hopefully we are good.
5431         for ((i=0; i<$warmup_files; i++)); do
5432                 idx=$($LFS getstripe -i $TDIR/w$i)
5433                 [ $idx -ne 0 ] && continue
5434                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5435         done
5436         $LCTL get_param $proc_osc0/cur_dirty_bytes
5437         $LCTL get_param $proc_osc0/cur_grant_bytes
5438
5439         # perform the real test
5440         $LCTL set_param $proc_osc0/rpc_stats 0
5441         for ((;i<$files; i++)); do
5442                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5443                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5444         done
5445         sync
5446         $LCTL get_param $proc_osc0/rpc_stats
5447
5448         local percent=0
5449         local have_ppr=false
5450         $LCTL get_param $proc_osc0/rpc_stats |
5451                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5452                         # skip lines until we are at the RPC histogram data
5453                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5454                         $have_ppr || continue
5455
5456                         # we only want the percent stat for < 16 pages
5457                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5458
5459                         percent=$((percent + WPCT))
5460                         if [[ $percent -gt 15 ]]; then
5461                                 error "less than 16-pages write RPCs" \
5462                                       "$percent% > 15%"
5463                                 break
5464                         fi
5465                 done
5466         rm -rf $TDIR
5467 }
5468 run_test 42e "verify sub-RPC writes are not done synchronously"
5469
5470 test_43A() { # was test_43
5471         test_mkdir $DIR/$tdir
5472         cp -p /bin/ls $DIR/$tdir/$tfile
5473         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5474         pid=$!
5475         # give multiop a chance to open
5476         sleep 1
5477
5478         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5479         kill -USR1 $pid
5480         # Wait for multiop to exit
5481         wait $pid
5482 }
5483 run_test 43A "execution of file opened for write should return -ETXTBSY"
5484
5485 test_43a() {
5486         test_mkdir $DIR/$tdir
5487         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5488         $DIR/$tdir/sleep 60 &
5489         SLEEP_PID=$!
5490         # Make sure exec of $tdir/sleep wins race with truncate
5491         sleep 1
5492         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5493         kill $SLEEP_PID
5494 }
5495 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5496
5497 test_43b() {
5498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5499
5500         test_mkdir $DIR/$tdir
5501         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5502         $DIR/$tdir/sleep 60 &
5503         SLEEP_PID=$!
5504         # Make sure exec of $tdir/sleep wins race with truncate
5505         sleep 1
5506         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5507         kill $SLEEP_PID
5508 }
5509 run_test 43b "truncate of file being executed should return -ETXTBSY"
5510
5511 test_43c() {
5512         local testdir="$DIR/$tdir"
5513         test_mkdir $testdir
5514         cp $SHELL $testdir/
5515         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5516                 ( cd $testdir && md5sum -c )
5517 }
5518 run_test 43c "md5sum of copy into lustre"
5519
5520 test_44A() { # was test_44
5521         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5522
5523         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5524         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5525 }
5526 run_test 44A "zero length read from a sparse stripe"
5527
5528 test_44a() {
5529         local nstripe=$($LFS getstripe -c -d $DIR)
5530         [ -z "$nstripe" ] && skip "can't get stripe info"
5531         [[ $nstripe -gt $OSTCOUNT ]] &&
5532                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5533
5534         local stride=$($LFS getstripe -S -d $DIR)
5535         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5536                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5537         fi
5538
5539         OFFSETS="0 $((stride/2)) $((stride-1))"
5540         for offset in $OFFSETS; do
5541                 for i in $(seq 0 $((nstripe-1))); do
5542                         local GLOBALOFFSETS=""
5543                         # size in Bytes
5544                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5545                         local myfn=$DIR/d44a-$size
5546                         echo "--------writing $myfn at $size"
5547                         ll_sparseness_write $myfn $size ||
5548                                 error "ll_sparseness_write"
5549                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5550                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5551                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5552
5553                         for j in $(seq 0 $((nstripe-1))); do
5554                                 # size in Bytes
5555                                 size=$((((j + $nstripe )*$stride + $offset)))
5556                                 ll_sparseness_write $myfn $size ||
5557                                         error "ll_sparseness_write"
5558                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5559                         done
5560                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5561                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5562                         rm -f $myfn
5563                 done
5564         done
5565 }
5566 run_test 44a "test sparse pwrite ==============================="
5567
5568 dirty_osc_total() {
5569         tot=0
5570         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5571                 tot=$(($tot + $d))
5572         done
5573         echo $tot
5574 }
5575 do_dirty_record() {
5576         before=`dirty_osc_total`
5577         echo executing "\"$*\""
5578         eval $*
5579         after=`dirty_osc_total`
5580         echo before $before, after $after
5581 }
5582 test_45() {
5583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5584
5585         f="$DIR/f45"
5586         # Obtain grants from OST if it supports it
5587         echo blah > ${f}_grant
5588         stop_writeback
5589         sync
5590         do_dirty_record "echo blah > $f"
5591         [[ $before -eq $after ]] && error "write wasn't cached"
5592         do_dirty_record "> $f"
5593         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5594         do_dirty_record "echo blah > $f"
5595         [[ $before -eq $after ]] && error "write wasn't cached"
5596         do_dirty_record "sync"
5597         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5598         do_dirty_record "echo blah > $f"
5599         [[ $before -eq $after ]] && error "write wasn't cached"
5600         do_dirty_record "cancel_lru_locks osc"
5601         [[ $before -gt $after ]] ||
5602                 error "lock cancellation didn't lower dirty count"
5603         start_writeback
5604 }
5605 run_test 45 "osc io page accounting ============================"
5606
5607 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5608 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5609 # objects offset and an assert hit when an rpc was built with 1023's mapped
5610 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5611 test_46() {
5612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5613
5614         f="$DIR/f46"
5615         stop_writeback
5616         sync
5617         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5618         sync
5619         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5620         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5621         sync
5622         start_writeback
5623 }
5624 run_test 46 "dirtying a previously written page ================"
5625
5626 # test_47 is removed "Device nodes check" is moved to test_28
5627
5628 test_48a() { # bug 2399
5629         [ "$mds1_FSTYPE" = "zfs" ] &&
5630         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5631                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5632
5633         test_mkdir $DIR/$tdir
5634         cd $DIR/$tdir
5635         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5636         test_mkdir $DIR/$tdir
5637         touch foo || error "'touch foo' failed after recreating cwd"
5638         test_mkdir bar
5639         touch .foo || error "'touch .foo' failed after recreating cwd"
5640         test_mkdir .bar
5641         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5642         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5643         cd . || error "'cd .' failed after recreating cwd"
5644         mkdir . && error "'mkdir .' worked after recreating cwd"
5645         rmdir . && error "'rmdir .' worked after recreating cwd"
5646         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5647         cd .. || error "'cd ..' failed after recreating cwd"
5648 }
5649 run_test 48a "Access renamed working dir (should return errors)="
5650
5651 test_48b() { # bug 2399
5652         rm -rf $DIR/$tdir
5653         test_mkdir $DIR/$tdir
5654         cd $DIR/$tdir
5655         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5656         touch foo && error "'touch foo' worked after removing cwd"
5657         mkdir foo && error "'mkdir foo' worked after removing cwd"
5658         touch .foo && error "'touch .foo' worked after removing cwd"
5659         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5660         ls . > /dev/null && error "'ls .' worked after removing cwd"
5661         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5662         mkdir . && error "'mkdir .' worked after removing cwd"
5663         rmdir . && error "'rmdir .' worked after removing cwd"
5664         ln -s . foo && error "'ln -s .' worked after removing cwd"
5665         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5666 }
5667 run_test 48b "Access removed working dir (should return errors)="
5668
5669 test_48c() { # bug 2350
5670         #lctl set_param debug=-1
5671         #set -vx
5672         rm -rf $DIR/$tdir
5673         test_mkdir -p $DIR/$tdir/dir
5674         cd $DIR/$tdir/dir
5675         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5676         $TRACE touch foo && error "touch foo worked after removing cwd"
5677         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5678         touch .foo && error "touch .foo worked after removing cwd"
5679         mkdir .foo && error "mkdir .foo worked after removing cwd"
5680         $TRACE ls . && error "'ls .' worked after removing cwd"
5681         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5682         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5683         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5684         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5685         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5686 }
5687 run_test 48c "Access removed working subdir (should return errors)"
5688
5689 test_48d() { # bug 2350
5690         #lctl set_param debug=-1
5691         #set -vx
5692         rm -rf $DIR/$tdir
5693         test_mkdir -p $DIR/$tdir/dir
5694         cd $DIR/$tdir/dir
5695         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5696         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5697         $TRACE touch foo && error "'touch foo' worked after removing parent"
5698         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5699         touch .foo && error "'touch .foo' worked after removing parent"
5700         mkdir .foo && error "mkdir .foo worked after removing parent"
5701         $TRACE ls . && error "'ls .' worked after removing parent"
5702         $TRACE ls .. && error "'ls ..' worked after removing parent"
5703         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5704         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5705         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5706         true
5707 }
5708 run_test 48d "Access removed parent subdir (should return errors)"
5709
5710 test_48e() { # bug 4134
5711         #lctl set_param debug=-1
5712         #set -vx
5713         rm -rf $DIR/$tdir
5714         test_mkdir -p $DIR/$tdir/dir
5715         cd $DIR/$tdir/dir
5716         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5717         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5718         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5719         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5720         # On a buggy kernel addition of "touch foo" after cd .. will
5721         # produce kernel oops in lookup_hash_it
5722         touch ../foo && error "'cd ..' worked after recreate parent"
5723         cd $DIR
5724         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5725 }
5726 run_test 48e "Access to recreated parent subdir (should return errors)"
5727
5728 test_48f() {
5729         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5730                 skip "need MDS >= 2.13.55"
5731         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5732         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5733                 skip "needs different host for mdt1 mdt2"
5734         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5735
5736         $LFS mkdir -i0 $DIR/$tdir
5737         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5738
5739         for d in sub1 sub2 sub3; do
5740                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5741                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5742                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5743         done
5744
5745         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5746 }
5747 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5748
5749 test_49() { # LU-1030
5750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5751         remote_ost_nodsh && skip "remote OST with nodsh"
5752
5753         # get ost1 size - $FSNAME-OST0000
5754         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5755                 awk '{ print $4 }')
5756         # write 800M at maximum
5757         [[ $ost1_size -lt 2 ]] && ost1_size=2
5758         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5759
5760         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5761         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5762         local dd_pid=$!
5763
5764         # change max_pages_per_rpc while writing the file
5765         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5766         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5767         # loop until dd process exits
5768         while ps ax -opid | grep -wq $dd_pid; do
5769                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5770                 sleep $((RANDOM % 5 + 1))
5771         done
5772         # restore original max_pages_per_rpc
5773         $LCTL set_param $osc1_mppc=$orig_mppc
5774         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5775 }
5776 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5777
5778 test_50() {
5779         # bug 1485
5780         test_mkdir $DIR/$tdir
5781         cd $DIR/$tdir
5782         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5783 }
5784 run_test 50 "special situations: /proc symlinks  ==============="
5785
5786 test_51a() {    # was test_51
5787         # bug 1516 - create an empty entry right after ".." then split dir
5788         test_mkdir -c1 $DIR/$tdir
5789         touch $DIR/$tdir/foo
5790         $MCREATE $DIR/$tdir/bar
5791         rm $DIR/$tdir/foo
5792         createmany -m $DIR/$tdir/longfile 201
5793         FNUM=202
5794         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5795                 $MCREATE $DIR/$tdir/longfile$FNUM
5796                 FNUM=$(($FNUM + 1))
5797                 echo -n "+"
5798         done
5799         echo
5800         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5801 }
5802 run_test 51a "special situations: split htree with empty entry =="
5803
5804 cleanup_print_lfs_df () {
5805         trap 0
5806         $LFS df
5807         $LFS df -i
5808 }
5809
5810 test_51b() {
5811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5812
5813         local dir=$DIR/$tdir
5814         local nrdirs=$((65536 + 100))
5815
5816         # cleanup the directory
5817         rm -fr $dir
5818
5819         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5820
5821         $LFS df
5822         $LFS df -i
5823         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5824         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5825         [[ $numfree -lt $nrdirs ]] &&
5826                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5827
5828         # need to check free space for the directories as well
5829         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5830         numfree=$(( blkfree / $(fs_inode_ksize) ))
5831         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5832
5833         trap cleanup_print_lfs_df EXIT
5834
5835         # create files
5836         createmany -d $dir/d $nrdirs || {
5837                 unlinkmany $dir/d $nrdirs
5838                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5839         }
5840
5841         # really created :
5842         nrdirs=$(ls -U $dir | wc -l)
5843
5844         # unlink all but 100 subdirectories, then check it still works
5845         local left=100
5846         local delete=$((nrdirs - left))
5847
5848         $LFS df
5849         $LFS df -i
5850
5851         # for ldiskfs the nlink count should be 1, but this is OSD specific
5852         # and so this is listed for informational purposes only
5853         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5854         unlinkmany -d $dir/d $delete ||
5855                 error "unlink of first $delete subdirs failed"
5856
5857         echo "nlink between: $(stat -c %h $dir)"
5858         local found=$(ls -U $dir | wc -l)
5859         [ $found -ne $left ] &&
5860                 error "can't find subdirs: found only $found, expected $left"
5861
5862         unlinkmany -d $dir/d $delete $left ||
5863                 error "unlink of second $left subdirs failed"
5864         # regardless of whether the backing filesystem tracks nlink accurately
5865         # or not, the nlink count shouldn't be more than "." and ".." here
5866         local after=$(stat -c %h $dir)
5867         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5868                 echo "nlink after: $after"
5869
5870         cleanup_print_lfs_df
5871 }
5872 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5873
5874 test_51d_sub() {
5875         local stripecount=$1
5876         local nfiles=$((200 * $OSTCOUNT))
5877
5878         log "create files with stripecount=$stripecount"
5879         $LFS setstripe -C $stripecount $DIR/$tdir
5880         createmany -o $DIR/$tdir/t- $nfiles
5881         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5882         for ((n = 0; n < $OSTCOUNT; n++)); do
5883                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5884                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5885                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5886                             '($1 == '$n') { objs += 1 } \
5887                             END { printf("%0.0f", objs) }')
5888                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5889         done
5890         unlinkmany $DIR/$tdir/t- $nfiles
5891         rm  -f $TMP/$tfile
5892
5893         local nlast
5894         local min=4
5895         local max=5 # allow variance of (1 - $min/$max) = 20% by default
5896
5897         # For some combinations of stripecount and OSTCOUNT current code
5898         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5899         # than others. Rather than skipping this test entirely, check that
5900         # and keep testing to ensure imbalance does not get worse. LU-15282
5901         (( (OSTCOUNT == 6 && stripecount == 4) ||
5902            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5903            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5904         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5905                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5906                         { $LFS df && $LFS df -i &&
5907                         error "OST $n has fewer objects vs. OST $nlast " \
5908                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5909                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5910                         { $LFS df && $LFS df -i &&
5911                         error "OST $n has fewer objects vs. OST $nlast " \
5912                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5913
5914                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5915                         { $LFS df && $LFS df -i &&
5916                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5917                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5918                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5919                         { $LFS df && $LFS df -i &&
5920                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5921                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5922         done
5923 }
5924
5925 test_51d() {
5926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5927         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5928
5929         local stripecount
5930         local qos_old=$(do_facet mds1 \
5931                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5932
5933         do_nodes $(comma_list $(mdts_nodes)) \
5934                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5935         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5936                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5937
5938         test_mkdir $DIR/$tdir
5939
5940         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5941                 test_51d_sub $stripecount
5942         done
5943 }
5944 run_test 51d "check object distribution"
5945
5946 test_51e() {
5947         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5948                 skip_env "ldiskfs only test"
5949         fi
5950
5951         test_mkdir -c1 $DIR/$tdir
5952         test_mkdir -c1 $DIR/$tdir/d0
5953
5954         touch $DIR/$tdir/d0/foo
5955         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5956                 error "file exceed 65000 nlink limit!"
5957         unlinkmany $DIR/$tdir/d0/f- 65001
5958         return 0
5959 }
5960 run_test 51e "check file nlink limit"
5961
5962 test_51f() {
5963         test_mkdir $DIR/$tdir
5964
5965         local max=100000
5966         local ulimit_old=$(ulimit -n)
5967         local spare=20 # number of spare fd's for scripts/libraries, etc.
5968         local mdt=$($LFS getstripe -m $DIR/$tdir)
5969         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5970
5971         echo "MDT$mdt numfree=$numfree, max=$max"
5972         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5973         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5974                 while ! ulimit -n $((numfree + spare)); do
5975                         numfree=$((numfree * 3 / 4))
5976                 done
5977                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5978         else
5979                 echo "left ulimit at $ulimit_old"
5980         fi
5981
5982         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5983                 unlinkmany $DIR/$tdir/f $numfree
5984                 error "create+open $numfree files in $DIR/$tdir failed"
5985         }
5986         ulimit -n $ulimit_old
5987
5988         # if createmany exits at 120s there will be fewer than $numfree files
5989         unlinkmany $DIR/$tdir/f $numfree || true
5990 }
5991 run_test 51f "check many open files limit"
5992
5993 test_52a() {
5994         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5995         test_mkdir $DIR/$tdir
5996         touch $DIR/$tdir/foo
5997         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5998         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5999         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6000         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6001         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6002                                         error "link worked"
6003         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6004         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6005         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6006                                                      error "lsattr"
6007         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6008         cp -r $DIR/$tdir $TMP/
6009         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6010 }
6011 run_test 52a "append-only flag test (should return errors)"
6012
6013 test_52b() {
6014         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6015         test_mkdir $DIR/$tdir
6016         touch $DIR/$tdir/foo
6017         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6018         cat test > $DIR/$tdir/foo && error "cat test worked"
6019         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6020         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6021         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6022                                         error "link worked"
6023         echo foo >> $DIR/$tdir/foo && error "echo worked"
6024         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6025         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6026         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6027         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6028                                                         error "lsattr"
6029         chattr -i $DIR/$tdir/foo || error "chattr failed"
6030
6031         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6032 }
6033 run_test 52b "immutable flag test (should return errors) ======="
6034
6035 test_53() {
6036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6037         remote_mds_nodsh && skip "remote MDS with nodsh"
6038         remote_ost_nodsh && skip "remote OST with nodsh"
6039
6040         local param
6041         local param_seq
6042         local ostname
6043         local mds_last
6044         local mds_last_seq
6045         local ost_last
6046         local ost_last_seq
6047         local ost_last_id
6048         local ostnum
6049         local node
6050         local found=false
6051         local support_last_seq=true
6052
6053         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6054                 support_last_seq=false
6055
6056         # only test MDT0000
6057         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6058         local value
6059         for value in $(do_facet $SINGLEMDS \
6060                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6061                 param=$(echo ${value[0]} | cut -d "=" -f1)
6062                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6063
6064                 if $support_last_seq; then
6065                         param_seq=$(echo $param |
6066                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6067                         mds_last_seq=$(do_facet $SINGLEMDS \
6068                                        $LCTL get_param -n $param_seq)
6069                 fi
6070                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6071
6072                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6073                 node=$(facet_active_host ost$((ostnum+1)))
6074                 param="obdfilter.$ostname.last_id"
6075                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6076                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6077                         ost_last_id=$ost_last
6078
6079                         if $support_last_seq; then
6080                                 ost_last_id=$(echo $ost_last |
6081                                               awk -F':' '{print $2}' |
6082                                               sed -e "s/^0x//g")
6083                                 ost_last_seq=$(echo $ost_last |
6084                                                awk -F':' '{print $1}')
6085                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6086                         fi
6087
6088                         if [[ $ost_last_id != $mds_last ]]; then
6089                                 error "$ost_last_id != $mds_last"
6090                         else
6091                                 found=true
6092                                 break
6093                         fi
6094                 done
6095         done
6096         $found || error "can not match last_seq/last_id for $mdtosc"
6097         return 0
6098 }
6099 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6100
6101 test_54a() {
6102         perl -MSocket -e ';' || skip "no Socket perl module installed"
6103
6104         $SOCKETSERVER $DIR/socket ||
6105                 error "$SOCKETSERVER $DIR/socket failed: $?"
6106         $SOCKETCLIENT $DIR/socket ||
6107                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6108         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6109 }
6110 run_test 54a "unix domain socket test =========================="
6111
6112 test_54b() {
6113         f="$DIR/f54b"
6114         mknod $f c 1 3
6115         chmod 0666 $f
6116         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6117 }
6118 run_test 54b "char device works in lustre ======================"
6119
6120 find_loop_dev() {
6121         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6122         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6123         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6124
6125         for i in $(seq 3 7); do
6126                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6127                 LOOPDEV=$LOOPBASE$i
6128                 LOOPNUM=$i
6129                 break
6130         done
6131 }
6132
6133 cleanup_54c() {
6134         local rc=0
6135         loopdev="$DIR/loop54c"
6136
6137         trap 0
6138         $UMOUNT $DIR/$tdir || rc=$?
6139         losetup -d $loopdev || true
6140         losetup -d $LOOPDEV || true
6141         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6142         return $rc
6143 }
6144
6145 test_54c() {
6146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6147
6148         loopdev="$DIR/loop54c"
6149
6150         find_loop_dev
6151         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6152         trap cleanup_54c EXIT
6153         mknod $loopdev b 7 $LOOPNUM
6154         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6155         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6156         losetup $loopdev $DIR/$tfile ||
6157                 error "can't set up $loopdev for $DIR/$tfile"
6158         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6159         test_mkdir $DIR/$tdir
6160         mount -t ext2 $loopdev $DIR/$tdir ||
6161                 error "error mounting $loopdev on $DIR/$tdir"
6162         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6163                 error "dd write"
6164         df $DIR/$tdir
6165         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6166                 error "dd read"
6167         cleanup_54c
6168 }
6169 run_test 54c "block device works in lustre ====================="
6170
6171 test_54d() {
6172         local pipe="$DIR/$tfile.pipe"
6173         local string="aaaaaa"
6174
6175         mknod $pipe p
6176         echo -n "$string" > $pipe &
6177         local result=$(cat $pipe)
6178         [[ "$result" == "$string" ]] || error "$result != $string"
6179 }
6180 run_test 54d "fifo device works in lustre ======================"
6181
6182 test_54e() {
6183         f="$DIR/f54e"
6184         string="aaaaaa"
6185         cp -aL /dev/console $f
6186         echo $string > $f || error "echo $string to $f failed"
6187 }
6188 run_test 54e "console/tty device works in lustre ======================"
6189
6190 test_56a() {
6191         local numfiles=3
6192         local numdirs=2
6193         local dir=$DIR/$tdir
6194
6195         rm -rf $dir
6196         test_mkdir -p $dir/dir
6197         for i in $(seq $numfiles); do
6198                 touch $dir/file$i
6199                 touch $dir/dir/file$i
6200         done
6201
6202         local numcomp=$($LFS getstripe --component-count $dir)
6203
6204         [[ $numcomp == 0 ]] && numcomp=1
6205
6206         # test lfs getstripe with --recursive
6207         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6208
6209         [[ $filenum -eq $((numfiles * 2)) ]] ||
6210                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6211         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6212         [[ $filenum -eq $numfiles ]] ||
6213                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6214         echo "$LFS getstripe showed obdidx or l_ost_idx"
6215
6216         # test lfs getstripe with file instead of dir
6217         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6218         [[ $filenum -eq 1 ]] ||
6219                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6220         echo "$LFS getstripe file1 passed"
6221
6222         #test lfs getstripe with --verbose
6223         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6224         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6225                 error "$LFS getstripe --verbose $dir: "\
6226                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6227         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6228                 error "$LFS getstripe $dir: showed lmm_magic"
6229
6230         #test lfs getstripe with -v prints lmm_fid
6231         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6232         local countfids=$((numdirs + numfiles * numcomp))
6233         [[ $filenum -eq $countfids ]] ||
6234                 error "$LFS getstripe -v $dir: "\
6235                       "got $filenum want $countfids lmm_fid"
6236         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6237                 error "$LFS getstripe $dir: showed lmm_fid by default"
6238         echo "$LFS getstripe --verbose passed"
6239
6240         #check for FID information
6241         local fid1=$($LFS getstripe --fid $dir/file1)
6242         local fid2=$($LFS getstripe --verbose $dir/file1 |
6243                      awk '/lmm_fid: / { print $2; exit; }')
6244         local fid3=$($LFS path2fid $dir/file1)
6245
6246         [ "$fid1" != "$fid2" ] &&
6247                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6248         [ "$fid1" != "$fid3" ] &&
6249                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6250         echo "$LFS getstripe --fid passed"
6251
6252         #test lfs getstripe with --obd
6253         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6254                 error "$LFS getstripe --obd wrong_uuid: should return error"
6255
6256         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6257
6258         local ostidx=1
6259         local obduuid=$(ostuuid_from_index $ostidx)
6260         local found=$($LFS getstripe -r --obd $obduuid $dir |
6261                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6262
6263         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6264         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6265                 ((filenum--))
6266         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6267                 ((filenum--))
6268
6269         [[ $found -eq $filenum ]] ||
6270                 error "$LFS getstripe --obd: found $found expect $filenum"
6271         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6272                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6273                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6274                 error "$LFS getstripe --obd: should not show file on other obd"
6275         echo "$LFS getstripe --obd passed"
6276 }
6277 run_test 56a "check $LFS getstripe"
6278
6279 test_56b() {
6280         local dir=$DIR/$tdir
6281         local numdirs=3
6282
6283         test_mkdir $dir
6284         for i in $(seq $numdirs); do
6285                 test_mkdir $dir/dir$i
6286         done
6287
6288         # test lfs getdirstripe default mode is non-recursion, which is
6289         # different from lfs getstripe
6290         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6291
6292         [[ $dircnt -eq 1 ]] ||
6293                 error "$LFS getdirstripe: found $dircnt, not 1"
6294         dircnt=$($LFS getdirstripe --recursive $dir |
6295                 grep -c lmv_stripe_count)
6296         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6297                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6298 }
6299 run_test 56b "check $LFS getdirstripe"
6300
6301 test_56c() {
6302         remote_ost_nodsh && skip "remote OST with nodsh"
6303
6304         local ost_idx=0
6305         local ost_name=$(ostname_from_index $ost_idx)
6306         local old_status=$(ost_dev_status $ost_idx)
6307         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6308
6309         [[ -z "$old_status" ]] ||
6310                 skip_env "OST $ost_name is in $old_status status"
6311
6312         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6313         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6314                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6315         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6316                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6317                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6318         fi
6319
6320         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6321                 error "$LFS df -v showing inactive devices"
6322         sleep_maxage
6323
6324         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6325
6326         [[ "$new_status" =~ "D" ]] ||
6327                 error "$ost_name status is '$new_status', missing 'D'"
6328         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6329                 [[ "$new_status" =~ "N" ]] ||
6330                         error "$ost_name status is '$new_status', missing 'N'"
6331         fi
6332         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6333                 [[ "$new_status" =~ "f" ]] ||
6334                         error "$ost_name status is '$new_status', missing 'f'"
6335         fi
6336
6337         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6338         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6339                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6340         [[ -z "$p" ]] && restore_lustre_params < $p || true
6341         sleep_maxage
6342
6343         new_status=$(ost_dev_status $ost_idx)
6344         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6345                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6346         # can't check 'f' as devices may actually be on flash
6347 }
6348 run_test 56c "check 'lfs df' showing device status"
6349
6350 test_56d() {
6351         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6352         local osts=$($LFS df -v $MOUNT | grep -c OST)
6353
6354         $LFS df $MOUNT
6355
6356         (( mdts == MDSCOUNT )) ||
6357                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6358         (( osts == OSTCOUNT )) ||
6359                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6360 }
6361 run_test 56d "'lfs df -v' prints only configured devices"
6362
6363 test_56e() {
6364         err_enoent=2 # No such file or directory
6365         err_eopnotsupp=95 # Operation not supported
6366
6367         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6368         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6369
6370         # Check for handling of path not exists
6371         output=$($LFS df $enoent_mnt 2>&1)
6372         ret=$?
6373
6374         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6375         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6376                 error "expect failure $err_enoent, not $ret"
6377
6378         # Check for handling of non-Lustre FS
6379         output=$($LFS df $notsup_mnt)
6380         ret=$?
6381
6382         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6383         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6384                 error "expect success $err_eopnotsupp, not $ret"
6385
6386         # Check for multiple LustreFS argument
6387         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6388         ret=$?
6389
6390         [[ $output -eq 3 && $ret -eq 0 ]] ||
6391                 error "expect success 3, not $output, rc = $ret"
6392
6393         # Check for correct non-Lustre FS handling among multiple
6394         # LustreFS argument
6395         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6396                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6397         ret=$?
6398
6399         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6400                 error "expect success 2, not $output, rc = $ret"
6401 }
6402 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6403
6404 NUMFILES=3
6405 NUMDIRS=3
6406 setup_56() {
6407         local local_tdir="$1"
6408         local local_numfiles="$2"
6409         local local_numdirs="$3"
6410         local dir_params="$4"
6411         local dir_stripe_params="$5"
6412
6413         if [ ! -d "$local_tdir" ] ; then
6414                 test_mkdir -p $dir_stripe_params $local_tdir
6415                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6416                 for i in $(seq $local_numfiles) ; do
6417                         touch $local_tdir/file$i
6418                 done
6419                 for i in $(seq $local_numdirs) ; do
6420                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6421                         for j in $(seq $local_numfiles) ; do
6422                                 touch $local_tdir/dir$i/file$j
6423                         done
6424                 done
6425         fi
6426 }
6427
6428 setup_56_special() {
6429         local local_tdir=$1
6430         local local_numfiles=$2
6431         local local_numdirs=$3
6432
6433         setup_56 $local_tdir $local_numfiles $local_numdirs
6434
6435         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6436                 for i in $(seq $local_numfiles) ; do
6437                         mknod $local_tdir/loop${i}b b 7 $i
6438                         mknod $local_tdir/null${i}c c 1 3
6439                         ln -s $local_tdir/file1 $local_tdir/link${i}
6440                 done
6441                 for i in $(seq $local_numdirs) ; do
6442                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6443                         mknod $local_tdir/dir$i/null${i}c c 1 3
6444                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6445                 done
6446         fi
6447 }
6448
6449 test_56g() {
6450         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6451         local expected=$(($NUMDIRS + 2))
6452
6453         setup_56 $dir $NUMFILES $NUMDIRS
6454
6455         # test lfs find with -name
6456         for i in $(seq $NUMFILES) ; do
6457                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6458
6459                 [ $nums -eq $expected ] ||
6460                         error "lfs find -name '*$i' $dir wrong: "\
6461                               "found $nums, expected $expected"
6462         done
6463 }
6464 run_test 56g "check lfs find -name"
6465
6466 test_56h() {
6467         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6468         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6469
6470         setup_56 $dir $NUMFILES $NUMDIRS
6471
6472         # test lfs find with ! -name
6473         for i in $(seq $NUMFILES) ; do
6474                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6475
6476                 [ $nums -eq $expected ] ||
6477                         error "lfs find ! -name '*$i' $dir wrong: "\
6478                               "found $nums, expected $expected"
6479         done
6480 }
6481 run_test 56h "check lfs find ! -name"
6482
6483 test_56i() {
6484         local dir=$DIR/$tdir
6485
6486         test_mkdir $dir
6487
6488         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6489         local out=$($cmd)
6490
6491         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6492 }
6493 run_test 56i "check 'lfs find -ost UUID' skips directories"
6494
6495 test_56j() {
6496         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6497
6498         setup_56_special $dir $NUMFILES $NUMDIRS
6499
6500         local expected=$((NUMDIRS + 1))
6501         local cmd="$LFS find -type d $dir"
6502         local nums=$($cmd | wc -l)
6503
6504         [ $nums -eq $expected ] ||
6505                 error "'$cmd' wrong: found $nums, expected $expected"
6506 }
6507 run_test 56j "check lfs find -type d"
6508
6509 test_56k() {
6510         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6511
6512         setup_56_special $dir $NUMFILES $NUMDIRS
6513
6514         local expected=$(((NUMDIRS + 1) * NUMFILES))
6515         local cmd="$LFS find -type f $dir"
6516         local nums=$($cmd | wc -l)
6517
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520 }
6521 run_test 56k "check lfs find -type f"
6522
6523 test_56l() {
6524         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6525
6526         setup_56_special $dir $NUMFILES $NUMDIRS
6527
6528         local expected=$((NUMDIRS + NUMFILES))
6529         local cmd="$LFS find -type b $dir"
6530         local nums=$($cmd | wc -l)
6531
6532         [ $nums -eq $expected ] ||
6533                 error "'$cmd' wrong: found $nums, expected $expected"
6534 }
6535 run_test 56l "check lfs find -type b"
6536
6537 test_56m() {
6538         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6539
6540         setup_56_special $dir $NUMFILES $NUMDIRS
6541
6542         local expected=$((NUMDIRS + NUMFILES))
6543         local cmd="$LFS find -type c $dir"
6544         local nums=$($cmd | wc -l)
6545         [ $nums -eq $expected ] ||
6546                 error "'$cmd' wrong: found $nums, expected $expected"
6547 }
6548 run_test 56m "check lfs find -type c"
6549
6550 test_56n() {
6551         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6552         setup_56_special $dir $NUMFILES $NUMDIRS
6553
6554         local expected=$((NUMDIRS + NUMFILES))
6555         local cmd="$LFS find -type l $dir"
6556         local nums=$($cmd | wc -l)
6557
6558         [ $nums -eq $expected ] ||
6559                 error "'$cmd' wrong: found $nums, expected $expected"
6560 }
6561 run_test 56n "check lfs find -type l"
6562
6563 test_56o() {
6564         local dir=$DIR/$tdir
6565
6566         setup_56 $dir $NUMFILES $NUMDIRS
6567         utime $dir/file1 > /dev/null || error "utime (1)"
6568         utime $dir/file2 > /dev/null || error "utime (2)"
6569         utime $dir/dir1 > /dev/null || error "utime (3)"
6570         utime $dir/dir2 > /dev/null || error "utime (4)"
6571         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6572         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6573
6574         local expected=4
6575         local nums=$($LFS find -mtime +0 $dir | wc -l)
6576
6577         [ $nums -eq $expected ] ||
6578                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6579
6580         expected=12
6581         cmd="$LFS find -mtime 0 $dir"
6582         nums=$($cmd | wc -l)
6583         [ $nums -eq $expected ] ||
6584                 error "'$cmd' wrong: found $nums, expected $expected"
6585 }
6586 run_test 56o "check lfs find -mtime for old files"
6587
6588 test_56ob() {
6589         local dir=$DIR/$tdir
6590         local expected=1
6591         local count=0
6592
6593         # just to make sure there is something that won't be found
6594         test_mkdir $dir
6595         touch $dir/$tfile.now
6596
6597         for age in year week day hour min; do
6598                 count=$((count + 1))
6599
6600                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6601                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6602                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6603
6604                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6605                 local nums=$($cmd | wc -l)
6606                 [ $nums -eq $expected ] ||
6607                         error "'$cmd' wrong: found $nums, expected $expected"
6608
6609                 cmd="$LFS find $dir -atime $count${age:0:1}"
6610                 nums=$($cmd | wc -l)
6611                 [ $nums -eq $expected ] ||
6612                         error "'$cmd' wrong: found $nums, expected $expected"
6613         done
6614
6615         sleep 2
6616         cmd="$LFS find $dir -ctime +1s -type f"
6617         nums=$($cmd | wc -l)
6618         (( $nums == $count * 2 + 1)) ||
6619                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6620 }
6621 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6622
6623 test_newerXY_base() {
6624         local x=$1
6625         local y=$2
6626         local dir=$DIR/$tdir
6627         local ref
6628         local negref
6629
6630         if [ $y == "t" ]; then
6631                 if [ $x == "b" ]; then
6632                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6633                 else
6634                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6635                 fi
6636         else
6637                 ref=$DIR/$tfile.newer.$x$y
6638                 touch $ref || error "touch $ref failed"
6639         fi
6640
6641         echo "before = $ref"
6642         sleep 2
6643         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6644         sleep 2
6645         if [ $y == "t" ]; then
6646                 if [ $x == "b" ]; then
6647                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6648                 else
6649                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6650                 fi
6651         else
6652                 negref=$DIR/$tfile.negnewer.$x$y
6653                 touch $negref || error "touch $negref failed"
6654         fi
6655
6656         echo "after = $negref"
6657         local cmd="$LFS find $dir -newer$x$y $ref"
6658         local nums=$(eval $cmd | wc -l)
6659         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6660
6661         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6662                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6663
6664         cmd="$LFS find $dir ! -newer$x$y $negref"
6665         nums=$(eval $cmd | wc -l)
6666         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6667                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6668
6669         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6670         nums=$(eval $cmd | wc -l)
6671         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6672                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6673
6674         rm -rf $DIR/*
6675 }
6676
6677 test_56oc() {
6678         test_newerXY_base "a" "a"
6679         test_newerXY_base "a" "m"
6680         test_newerXY_base "a" "c"
6681         test_newerXY_base "m" "a"
6682         test_newerXY_base "m" "m"
6683         test_newerXY_base "m" "c"
6684         test_newerXY_base "c" "a"
6685         test_newerXY_base "c" "m"
6686         test_newerXY_base "c" "c"
6687
6688         [[ -n "$sles_version" ]] &&
6689                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6690
6691         test_newerXY_base "a" "t"
6692         test_newerXY_base "m" "t"
6693         test_newerXY_base "c" "t"
6694
6695         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6696            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6697                 ! btime_supported && echo "btime unsupported" && return 0
6698
6699         test_newerXY_base "b" "b"
6700         test_newerXY_base "b" "t"
6701 }
6702 run_test 56oc "check lfs find -newerXY work"
6703
6704 btime_supported() {
6705         local dir=$DIR/$tdir
6706         local rc
6707
6708         mkdir -p $dir
6709         touch $dir/$tfile
6710         $LFS find $dir -btime -1d -type f
6711         rc=$?
6712         rm -rf $dir
6713         return $rc
6714 }
6715
6716 test_56od() {
6717         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6718                 ! btime_supported && skip "btime unsupported on MDS"
6719
6720         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6721                 ! btime_supported && skip "btime unsupported on clients"
6722
6723         local dir=$DIR/$tdir
6724         local ref=$DIR/$tfile.ref
6725         local negref=$DIR/$tfile.negref
6726
6727         mkdir $dir || error "mkdir $dir failed"
6728         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6729         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6730         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6731         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6732         touch $ref || error "touch $ref failed"
6733         # sleep 3 seconds at least
6734         sleep 3
6735
6736         local before=$(do_facet mds1 date +%s)
6737         local skew=$(($(date +%s) - before + 1))
6738
6739         if (( skew < 0 && skew > -5 )); then
6740                 sleep $((0 - skew + 1))
6741                 skew=0
6742         fi
6743
6744         # Set the dir stripe params to limit files all on MDT0,
6745         # otherwise we need to calc the max clock skew between
6746         # the client and MDTs.
6747         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6748         sleep 2
6749         touch $negref || error "touch $negref failed"
6750
6751         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6752         local nums=$($cmd | wc -l)
6753         local expected=$(((NUMFILES + 1) * NUMDIRS))
6754
6755         [ $nums -eq $expected ] ||
6756                 error "'$cmd' wrong: found $nums, expected $expected"
6757
6758         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6759         nums=$($cmd | wc -l)
6760         expected=$((NUMFILES + 1))
6761         [ $nums -eq $expected ] ||
6762                 error "'$cmd' wrong: found $nums, expected $expected"
6763
6764         [ $skew -lt 0 ] && return
6765
6766         local after=$(do_facet mds1 date +%s)
6767         local age=$((after - before + 1 + skew))
6768
6769         cmd="$LFS find $dir -btime -${age}s -type f"
6770         nums=$($cmd | wc -l)
6771         expected=$(((NUMFILES + 1) * NUMDIRS))
6772
6773         echo "Clock skew between client and server: $skew, age:$age"
6774         [ $nums -eq $expected ] ||
6775                 error "'$cmd' wrong: found $nums, expected $expected"
6776
6777         expected=$(($NUMDIRS + 1))
6778         cmd="$LFS find $dir -btime -${age}s -type d"
6779         nums=$($cmd | wc -l)
6780         [ $nums -eq $expected ] ||
6781                 error "'$cmd' wrong: found $nums, expected $expected"
6782         rm -f $ref $negref || error "Failed to remove $ref $negref"
6783 }
6784 run_test 56od "check lfs find -btime with units"
6785
6786 test_56p() {
6787         [ $RUNAS_ID -eq $UID ] &&
6788                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6789
6790         local dir=$DIR/$tdir
6791
6792         setup_56 $dir $NUMFILES $NUMDIRS
6793         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6794
6795         local expected=$NUMFILES
6796         local cmd="$LFS find -uid $RUNAS_ID $dir"
6797         local nums=$($cmd | wc -l)
6798
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801
6802         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6803         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6804         nums=$($cmd | wc -l)
6805         [ $nums -eq $expected ] ||
6806                 error "'$cmd' wrong: found $nums, expected $expected"
6807 }
6808 run_test 56p "check lfs find -uid and ! -uid"
6809
6810 test_56q() {
6811         [ $RUNAS_ID -eq $UID ] &&
6812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6813
6814         local dir=$DIR/$tdir
6815
6816         setup_56 $dir $NUMFILES $NUMDIRS
6817         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6818
6819         local expected=$NUMFILES
6820         local cmd="$LFS find -gid $RUNAS_GID $dir"
6821         local nums=$($cmd | wc -l)
6822
6823         [ $nums -eq $expected ] ||
6824                 error "'$cmd' wrong: found $nums, expected $expected"
6825
6826         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6827         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6828         nums=$($cmd | wc -l)
6829         [ $nums -eq $expected ] ||
6830                 error "'$cmd' wrong: found $nums, expected $expected"
6831 }
6832 run_test 56q "check lfs find -gid and ! -gid"
6833
6834 test_56r() {
6835         local dir=$DIR/$tdir
6836
6837         setup_56 $dir $NUMFILES $NUMDIRS
6838
6839         local expected=12
6840         local cmd="$LFS find -size 0 -type f -lazy $dir"
6841         local nums=$($cmd | wc -l)
6842
6843         [ $nums -eq $expected ] ||
6844                 error "'$cmd' wrong: found $nums, expected $expected"
6845         cmd="$LFS find -size 0 -type f $dir"
6846         nums=$($cmd | wc -l)
6847         [ $nums -eq $expected ] ||
6848                 error "'$cmd' wrong: found $nums, expected $expected"
6849
6850         expected=0
6851         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6852         nums=$($cmd | wc -l)
6853         [ $nums -eq $expected ] ||
6854                 error "'$cmd' wrong: found $nums, expected $expected"
6855         cmd="$LFS find ! -size 0 -type f $dir"
6856         nums=$($cmd | wc -l)
6857         [ $nums -eq $expected ] ||
6858                 error "'$cmd' wrong: found $nums, expected $expected"
6859
6860         echo "test" > $dir/$tfile
6861         echo "test2" > $dir/$tfile.2 && sync
6862         expected=1
6863         cmd="$LFS find -size 5 -type f -lazy $dir"
6864         nums=$($cmd | wc -l)
6865         [ $nums -eq $expected ] ||
6866                 error "'$cmd' wrong: found $nums, expected $expected"
6867         cmd="$LFS find -size 5 -type f $dir"
6868         nums=$($cmd | wc -l)
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871
6872         expected=1
6873         cmd="$LFS find -size +5 -type f -lazy $dir"
6874         nums=$($cmd | wc -l)
6875         [ $nums -eq $expected ] ||
6876                 error "'$cmd' wrong: found $nums, expected $expected"
6877         cmd="$LFS find -size +5 -type f $dir"
6878         nums=$($cmd | wc -l)
6879         [ $nums -eq $expected ] ||
6880                 error "'$cmd' wrong: found $nums, expected $expected"
6881
6882         expected=2
6883         cmd="$LFS find -size +0 -type f -lazy $dir"
6884         nums=$($cmd | wc -l)
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887         cmd="$LFS find -size +0 -type f $dir"
6888         nums=$($cmd | wc -l)
6889         [ $nums -eq $expected ] ||
6890                 error "'$cmd' wrong: found $nums, expected $expected"
6891
6892         expected=2
6893         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6894         nums=$($cmd | wc -l)
6895         [ $nums -eq $expected ] ||
6896                 error "'$cmd' wrong: found $nums, expected $expected"
6897         cmd="$LFS find ! -size -5 -type f $dir"
6898         nums=$($cmd | wc -l)
6899         [ $nums -eq $expected ] ||
6900                 error "'$cmd' wrong: found $nums, expected $expected"
6901
6902         expected=12
6903         cmd="$LFS find -size -5 -type f -lazy $dir"
6904         nums=$($cmd | wc -l)
6905         [ $nums -eq $expected ] ||
6906                 error "'$cmd' wrong: found $nums, expected $expected"
6907         cmd="$LFS find -size -5 -type f $dir"
6908         nums=$($cmd | wc -l)
6909         [ $nums -eq $expected ] ||
6910                 error "'$cmd' wrong: found $nums, expected $expected"
6911 }
6912 run_test 56r "check lfs find -size works"
6913
6914 test_56ra_sub() {
6915         local expected=$1
6916         local glimpses=$2
6917         local cmd="$3"
6918
6919         cancel_lru_locks $OSC
6920
6921         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6922         local nums=$($cmd | wc -l)
6923
6924         [ $nums -eq $expected ] ||
6925                 error "'$cmd' wrong: found $nums, expected $expected"
6926
6927         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6928
6929         if (( rpcs_before + glimpses != rpcs_after )); then
6930                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6931                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6932
6933                 if [[ $glimpses == 0 ]]; then
6934                         error "'$cmd' should not send glimpse RPCs to OST"
6935                 else
6936                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6937                 fi
6938         fi
6939 }
6940
6941 test_56ra() {
6942         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6943                 skip "MDS < 2.12.58 doesn't return LSOM data"
6944         local dir=$DIR/$tdir
6945         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6946
6947         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6948
6949         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6950         $LCTL set_param -n llite.*.statahead_agl=0
6951         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6952
6953         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6954         # open and close all files to ensure LSOM is updated
6955         cancel_lru_locks $OSC
6956         find $dir -type f | xargs cat > /dev/null
6957
6958         #   expect_found  glimpse_rpcs  command_to_run
6959         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6960         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6961         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6962         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6963
6964         echo "test" > $dir/$tfile
6965         echo "test2" > $dir/$tfile.2 && sync
6966         cancel_lru_locks $OSC
6967         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6968
6969         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6970         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6971         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6972         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6973
6974         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6975         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6976         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6977         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6978         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6979         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6980 }
6981 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6982
6983 test_56rb() {
6984         local dir=$DIR/$tdir
6985         local tmp=$TMP/$tfile.log
6986         local mdt_idx;
6987
6988         test_mkdir -p $dir || error "failed to mkdir $dir"
6989         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6990                 error "failed to setstripe $dir/$tfile"
6991         mdt_idx=$($LFS getdirstripe -i $dir)
6992         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6993
6994         stack_trap "rm -f $tmp" EXIT
6995         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6996         ! grep -q obd_uuid $tmp ||
6997                 error "failed to find --size +100K --ost 0 $dir"
6998         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6999         ! grep -q obd_uuid $tmp ||
7000                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7001 }
7002 run_test 56rb "check lfs find --size --ost/--mdt works"
7003
7004 test_56rc() {
7005         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7006         local dir=$DIR/$tdir
7007         local found
7008
7009         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7010         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7011         (( $MDSCOUNT > 2 )) &&
7012                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7013         mkdir $dir/$tdir-{1..10}
7014         touch $dir/$tfile-{1..10}
7015
7016         found=$($LFS find $dir --mdt-count 2 | wc -l)
7017         expect=11
7018         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7019
7020         found=$($LFS find $dir -T +1 | wc -l)
7021         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7022         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7023
7024         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7025         expect=11
7026         (( $found == $expect )) || error "found $found all_char, expect $expect"
7027
7028         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7029         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7030         (( $found == $expect )) || error "found $found all_char, expect $expect"
7031 }
7032 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7033
7034 test_56s() { # LU-611 #LU-9369
7035         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7036
7037         local dir=$DIR/$tdir
7038         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7039
7040         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7041         for i in $(seq $NUMDIRS); do
7042                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7043         done
7044
7045         local expected=$NUMDIRS
7046         local cmd="$LFS find -c $OSTCOUNT $dir"
7047         local nums=$($cmd | wc -l)
7048
7049         [ $nums -eq $expected ] || {
7050                 $LFS getstripe -R $dir
7051                 error "'$cmd' wrong: found $nums, expected $expected"
7052         }
7053
7054         expected=$((NUMDIRS + onestripe))
7055         cmd="$LFS find -stripe-count +0 -type f $dir"
7056         nums=$($cmd | wc -l)
7057         [ $nums -eq $expected ] || {
7058                 $LFS getstripe -R $dir
7059                 error "'$cmd' wrong: found $nums, expected $expected"
7060         }
7061
7062         expected=$onestripe
7063         cmd="$LFS find -stripe-count 1 -type f $dir"
7064         nums=$($cmd | wc -l)
7065         [ $nums -eq $expected ] || {
7066                 $LFS getstripe -R $dir
7067                 error "'$cmd' wrong: found $nums, expected $expected"
7068         }
7069
7070         cmd="$LFS find -stripe-count -2 -type f $dir"
7071         nums=$($cmd | wc -l)
7072         [ $nums -eq $expected ] || {
7073                 $LFS getstripe -R $dir
7074                 error "'$cmd' wrong: found $nums, expected $expected"
7075         }
7076
7077         expected=0
7078         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7079         nums=$($cmd | wc -l)
7080         [ $nums -eq $expected ] || {
7081                 $LFS getstripe -R $dir
7082                 error "'$cmd' wrong: found $nums, expected $expected"
7083         }
7084 }
7085 run_test 56s "check lfs find -stripe-count works"
7086
7087 test_56t() { # LU-611 #LU-9369
7088         local dir=$DIR/$tdir
7089
7090         setup_56 $dir 0 $NUMDIRS
7091         for i in $(seq $NUMDIRS); do
7092                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7093         done
7094
7095         local expected=$NUMDIRS
7096         local cmd="$LFS find -S 8M $dir"
7097         local nums=$($cmd | wc -l)
7098
7099         [ $nums -eq $expected ] || {
7100                 $LFS getstripe -R $dir
7101                 error "'$cmd' wrong: found $nums, expected $expected"
7102         }
7103         rm -rf $dir
7104
7105         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7106
7107         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7108
7109         expected=$(((NUMDIRS + 1) * NUMFILES))
7110         cmd="$LFS find -stripe-size 512k -type f $dir"
7111         nums=$($cmd | wc -l)
7112         [ $nums -eq $expected ] ||
7113                 error "'$cmd' wrong: found $nums, expected $expected"
7114
7115         cmd="$LFS find -stripe-size +320k -type f $dir"
7116         nums=$($cmd | wc -l)
7117         [ $nums -eq $expected ] ||
7118                 error "'$cmd' wrong: found $nums, expected $expected"
7119
7120         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7121         cmd="$LFS find -stripe-size +200k -type f $dir"
7122         nums=$($cmd | wc -l)
7123         [ $nums -eq $expected ] ||
7124                 error "'$cmd' wrong: found $nums, expected $expected"
7125
7126         cmd="$LFS find -stripe-size -640k -type f $dir"
7127         nums=$($cmd | wc -l)
7128         [ $nums -eq $expected ] ||
7129                 error "'$cmd' wrong: found $nums, expected $expected"
7130
7131         expected=4
7132         cmd="$LFS find -stripe-size 256k -type f $dir"
7133         nums=$($cmd | wc -l)
7134         [ $nums -eq $expected ] ||
7135                 error "'$cmd' wrong: found $nums, expected $expected"
7136
7137         cmd="$LFS find -stripe-size -320k -type f $dir"
7138         nums=$($cmd | wc -l)
7139         [ $nums -eq $expected ] ||
7140                 error "'$cmd' wrong: found $nums, expected $expected"
7141
7142         expected=0
7143         cmd="$LFS find -stripe-size 1024k -type f $dir"
7144         nums=$($cmd | wc -l)
7145         [ $nums -eq $expected ] ||
7146                 error "'$cmd' wrong: found $nums, expected $expected"
7147 }
7148 run_test 56t "check lfs find -stripe-size works"
7149
7150 test_56u() { # LU-611
7151         local dir=$DIR/$tdir
7152
7153         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7154
7155         if [[ $OSTCOUNT -gt 1 ]]; then
7156                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7157                 onestripe=4
7158         else
7159                 onestripe=0
7160         fi
7161
7162         local expected=$(((NUMDIRS + 1) * NUMFILES))
7163         local cmd="$LFS find -stripe-index 0 -type f $dir"
7164         local nums=$($cmd | wc -l)
7165
7166         [ $nums -eq $expected ] ||
7167                 error "'$cmd' wrong: found $nums, expected $expected"
7168
7169         expected=$onestripe
7170         cmd="$LFS find -stripe-index 1 -type f $dir"
7171         nums=$($cmd | wc -l)
7172         [ $nums -eq $expected ] ||
7173                 error "'$cmd' wrong: found $nums, expected $expected"
7174
7175         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7176         nums=$($cmd | wc -l)
7177         [ $nums -eq $expected ] ||
7178                 error "'$cmd' wrong: found $nums, expected $expected"
7179
7180         expected=0
7181         # This should produce an error and not return any files
7182         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7183         nums=$($cmd 2>/dev/null | wc -l)
7184         [ $nums -eq $expected ] ||
7185                 error "'$cmd' wrong: found $nums, expected $expected"
7186
7187         if [[ $OSTCOUNT -gt 1 ]]; then
7188                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7189                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7190                 nums=$($cmd | wc -l)
7191                 [ $nums -eq $expected ] ||
7192                         error "'$cmd' wrong: found $nums, expected $expected"
7193         fi
7194 }
7195 run_test 56u "check lfs find -stripe-index works"
7196
7197 test_56v() {
7198         local mdt_idx=0
7199         local dir=$DIR/$tdir
7200
7201         setup_56 $dir $NUMFILES $NUMDIRS
7202
7203         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7204         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7205
7206         for file in $($LFS find -m $UUID $dir); do
7207                 file_midx=$($LFS getstripe -m $file)
7208                 [ $file_midx -eq $mdt_idx ] ||
7209                         error "lfs find -m $UUID != getstripe -m $file_midx"
7210         done
7211 }
7212 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7213
7214 test_56w() {
7215         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7217
7218         local dir=$DIR/$tdir
7219
7220         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7221
7222         local stripe_size=$($LFS getstripe -S -d $dir) ||
7223                 error "$LFS getstripe -S -d $dir failed"
7224         stripe_size=${stripe_size%% *}
7225
7226         local file_size=$((stripe_size * OSTCOUNT))
7227         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7228         local required_space=$((file_num * file_size))
7229         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7230                            head -n1)
7231         [[ $free_space -le $((required_space / 1024)) ]] &&
7232                 skip_env "need $required_space, have $free_space kbytes"
7233
7234         local dd_bs=65536
7235         local dd_count=$((file_size / dd_bs))
7236
7237         # write data into the files
7238         local i
7239         local j
7240         local file
7241
7242         for i in $(seq $NUMFILES); do
7243                 file=$dir/file$i
7244                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7245                         error "write data into $file failed"
7246         done
7247         for i in $(seq $NUMDIRS); do
7248                 for j in $(seq $NUMFILES); do
7249                         file=$dir/dir$i/file$j
7250                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7251                                 error "write data into $file failed"
7252                 done
7253         done
7254
7255         # $LFS_MIGRATE will fail if hard link migration is unsupported
7256         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7257                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7258                         error "creating links to $dir/dir1/file1 failed"
7259         fi
7260
7261         local expected=-1
7262
7263         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7264
7265         # lfs_migrate file
7266         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7267
7268         echo "$cmd"
7269         eval $cmd || error "$cmd failed"
7270
7271         check_stripe_count $dir/file1 $expected
7272
7273         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7274         then
7275                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7276                 # OST 1 if it is on OST 0. This file is small enough to
7277                 # be on only one stripe.
7278                 file=$dir/migr_1_ost
7279                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7280                         error "write data into $file failed"
7281                 local obdidx=$($LFS getstripe -i $file)
7282                 local oldmd5=$(md5sum $file)
7283                 local newobdidx=0
7284
7285                 [[ $obdidx -eq 0 ]] && newobdidx=1
7286                 cmd="$LFS migrate -i $newobdidx $file"
7287                 echo $cmd
7288                 eval $cmd || error "$cmd failed"
7289
7290                 local realobdix=$($LFS getstripe -i $file)
7291                 local newmd5=$(md5sum $file)
7292
7293                 [[ $newobdidx -ne $realobdix ]] &&
7294                         error "new OST is different (was=$obdidx, "\
7295                               "wanted=$newobdidx, got=$realobdix)"
7296                 [[ "$oldmd5" != "$newmd5" ]] &&
7297                         error "md5sum differ: $oldmd5, $newmd5"
7298         fi
7299
7300         # lfs_migrate dir
7301         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7302         echo "$cmd"
7303         eval $cmd || error "$cmd failed"
7304
7305         for j in $(seq $NUMFILES); do
7306                 check_stripe_count $dir/dir1/file$j $expected
7307         done
7308
7309         # lfs_migrate works with lfs find
7310         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7311              $LFS_MIGRATE -y -c $expected"
7312         echo "$cmd"
7313         eval $cmd || error "$cmd failed"
7314
7315         for i in $(seq 2 $NUMFILES); do
7316                 check_stripe_count $dir/file$i $expected
7317         done
7318         for i in $(seq 2 $NUMDIRS); do
7319                 for j in $(seq $NUMFILES); do
7320                 check_stripe_count $dir/dir$i/file$j $expected
7321                 done
7322         done
7323 }
7324 run_test 56w "check lfs_migrate -c stripe_count works"
7325
7326 test_56wb() {
7327         local file1=$DIR/$tdir/file1
7328         local create_pool=false
7329         local initial_pool=$($LFS getstripe -p $DIR)
7330         local pool_list=()
7331         local pool=""
7332
7333         echo -n "Creating test dir..."
7334         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7335         echo "done."
7336
7337         echo -n "Creating test file..."
7338         touch $file1 || error "cannot create file"
7339         echo "done."
7340
7341         echo -n "Detecting existing pools..."
7342         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7343
7344         if [ ${#pool_list[@]} -gt 0 ]; then
7345                 echo "${pool_list[@]}"
7346                 for thispool in "${pool_list[@]}"; do
7347                         if [[ -z "$initial_pool" ||
7348                               "$initial_pool" != "$thispool" ]]; then
7349                                 pool="$thispool"
7350                                 echo "Using existing pool '$pool'"
7351                                 break
7352                         fi
7353                 done
7354         else
7355                 echo "none detected."
7356         fi
7357         if [ -z "$pool" ]; then
7358                 pool=${POOL:-testpool}
7359                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7360                 echo -n "Creating pool '$pool'..."
7361                 create_pool=true
7362                 pool_add $pool &> /dev/null ||
7363                         error "pool_add failed"
7364                 echo "done."
7365
7366                 echo -n "Adding target to pool..."
7367                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7368                         error "pool_add_targets failed"
7369                 echo "done."
7370         fi
7371
7372         echo -n "Setting pool using -p option..."
7373         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7374                 error "migrate failed rc = $?"
7375         echo "done."
7376
7377         echo -n "Verifying test file is in pool after migrating..."
7378         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7379                 error "file was not migrated to pool $pool"
7380         echo "done."
7381
7382         echo -n "Removing test file from pool '$pool'..."
7383         # "lfs migrate $file" won't remove the file from the pool
7384         # until some striping information is changed.
7385         $LFS migrate -c 1 $file1 &> /dev/null ||
7386                 error "cannot remove from pool"
7387         [ "$($LFS getstripe -p $file1)" ] &&
7388                 error "pool still set"
7389         echo "done."
7390
7391         echo -n "Setting pool using --pool option..."
7392         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7393                 error "migrate failed rc = $?"
7394         echo "done."
7395
7396         # Clean up
7397         rm -f $file1
7398         if $create_pool; then
7399                 destroy_test_pools 2> /dev/null ||
7400                         error "destroy test pools failed"
7401         fi
7402 }
7403 run_test 56wb "check lfs_migrate pool support"
7404
7405 test_56wc() {
7406         local file1="$DIR/$tdir/file1"
7407         local parent_ssize
7408         local parent_scount
7409         local cur_ssize
7410         local cur_scount
7411         local orig_ssize
7412
7413         echo -n "Creating test dir..."
7414         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7415         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7416                 error "cannot set stripe by '-S 1M -c 1'"
7417         echo "done"
7418
7419         echo -n "Setting initial stripe for test file..."
7420         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7421                 error "cannot set stripe"
7422         cur_ssize=$($LFS getstripe -S "$file1")
7423         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7424         echo "done."
7425
7426         # File currently set to -S 512K -c 1
7427
7428         # Ensure -c and -S options are rejected when -R is set
7429         echo -n "Verifying incompatible options are detected..."
7430         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7431                 error "incompatible -c and -R options not detected"
7432         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7433                 error "incompatible -S and -R options not detected"
7434         echo "done."
7435
7436         # Ensure unrecognized options are passed through to 'lfs migrate'
7437         echo -n "Verifying -S option is passed through to lfs migrate..."
7438         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7439                 error "migration failed"
7440         cur_ssize=$($LFS getstripe -S "$file1")
7441         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7442         echo "done."
7443
7444         # File currently set to -S 1M -c 1
7445
7446         # Ensure long options are supported
7447         echo -n "Verifying long options supported..."
7448         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7449                 error "long option without argument not supported"
7450         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7451                 error "long option with argument not supported"
7452         cur_ssize=$($LFS getstripe -S "$file1")
7453         [ $cur_ssize -eq 524288 ] ||
7454                 error "migrate --stripe-size $cur_ssize != 524288"
7455         echo "done."
7456
7457         # File currently set to -S 512K -c 1
7458
7459         if [ "$OSTCOUNT" -gt 1 ]; then
7460                 echo -n "Verifying explicit stripe count can be set..."
7461                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7462                         error "migrate failed"
7463                 cur_scount=$($LFS getstripe -c "$file1")
7464                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7465                 echo "done."
7466         fi
7467
7468         # File currently set to -S 512K -c 1 or -S 512K -c 2
7469
7470         # Ensure parent striping is used if -R is set, and no stripe
7471         # count or size is specified
7472         echo -n "Setting stripe for parent directory..."
7473         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7474                 error "cannot set stripe '-S 2M -c 1'"
7475         echo "done."
7476
7477         echo -n "Verifying restripe option uses parent stripe settings..."
7478         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7479         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7480         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7481                 error "migrate failed"
7482         cur_ssize=$($LFS getstripe -S "$file1")
7483         [ $cur_ssize -eq $parent_ssize ] ||
7484                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7485         cur_scount=$($LFS getstripe -c "$file1")
7486         [ $cur_scount -eq $parent_scount ] ||
7487                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7488         echo "done."
7489
7490         # File currently set to -S 1M -c 1
7491
7492         # Ensure striping is preserved if -R is not set, and no stripe
7493         # count or size is specified
7494         echo -n "Verifying striping size preserved when not specified..."
7495         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7496         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7497                 error "cannot set stripe on parent directory"
7498         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7499                 error "migrate failed"
7500         cur_ssize=$($LFS getstripe -S "$file1")
7501         [ $cur_ssize -eq $orig_ssize ] ||
7502                 error "migrate by default $cur_ssize != $orig_ssize"
7503         echo "done."
7504
7505         # Ensure file name properly detected when final option has no argument
7506         echo -n "Verifying file name properly detected..."
7507         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7508                 error "file name interpreted as option argument"
7509         echo "done."
7510
7511         # Clean up
7512         rm -f "$file1"
7513 }
7514 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7515
7516 test_56wd() {
7517         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7518
7519         local file1=$DIR/$tdir/file1
7520
7521         echo -n "Creating test dir..."
7522         test_mkdir $DIR/$tdir || error "cannot create dir"
7523         echo "done."
7524
7525         echo -n "Creating test file..."
7526         touch $file1
7527         echo "done."
7528
7529         # Ensure 'lfs migrate' will fail by using a non-existent option,
7530         # and make sure rsync is not called to recover
7531         echo -n "Make sure --no-rsync option works..."
7532         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7533                 grep -q 'refusing to fall back to rsync' ||
7534                 error "rsync was called with --no-rsync set"
7535         echo "done."
7536
7537         # Ensure rsync is called without trying 'lfs migrate' first
7538         echo -n "Make sure --rsync option works..."
7539         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7540                 grep -q 'falling back to rsync' &&
7541                 error "lfs migrate was called with --rsync set"
7542         echo "done."
7543
7544         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7545         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7546                 grep -q 'at the same time' ||
7547                 error "--rsync and --no-rsync accepted concurrently"
7548         echo "done."
7549
7550         # Clean up
7551         rm -f $file1
7552 }
7553 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7554
7555 test_56we() {
7556         local td=$DIR/$tdir
7557         local tf=$td/$tfile
7558
7559         test_mkdir $td || error "cannot create $td"
7560         touch $tf || error "cannot touch $tf"
7561
7562         echo -n "Make sure --non-direct|-D works..."
7563         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7564                 grep -q "lfs migrate --non-direct" ||
7565                 error "--non-direct option cannot work correctly"
7566         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7567                 grep -q "lfs migrate -D" ||
7568                 error "-D option cannot work correctly"
7569         echo "done."
7570 }
7571 run_test 56we "check lfs_migrate --non-direct|-D support"
7572
7573 test_56x() {
7574         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7575         check_swap_layouts_support
7576
7577         local dir=$DIR/$tdir
7578         local ref1=/etc/passwd
7579         local file1=$dir/file1
7580
7581         test_mkdir $dir || error "creating dir $dir"
7582         $LFS setstripe -c 2 $file1
7583         cp $ref1 $file1
7584         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7585         stripe=$($LFS getstripe -c $file1)
7586         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7587         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7588
7589         # clean up
7590         rm -f $file1
7591 }
7592 run_test 56x "lfs migration support"
7593
7594 test_56xa() {
7595         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7596         check_swap_layouts_support
7597
7598         local dir=$DIR/$tdir/$testnum
7599
7600         test_mkdir -p $dir
7601
7602         local ref1=/etc/passwd
7603         local file1=$dir/file1
7604
7605         $LFS setstripe -c 2 $file1
7606         cp $ref1 $file1
7607         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7608
7609         local stripe=$($LFS getstripe -c $file1)
7610
7611         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7612         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7613
7614         # clean up
7615         rm -f $file1
7616 }
7617 run_test 56xa "lfs migration --block support"
7618
7619 check_migrate_links() {
7620         local dir="$1"
7621         local file1="$dir/file1"
7622         local begin="$2"
7623         local count="$3"
7624         local runas="$4"
7625         local total_count=$(($begin + $count - 1))
7626         local symlink_count=10
7627         local uniq_count=10
7628
7629         if [ ! -f "$file1" ]; then
7630                 echo -n "creating initial file..."
7631                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7632                         error "cannot setstripe initial file"
7633                 echo "done"
7634
7635                 echo -n "creating symlinks..."
7636                 for s in $(seq 1 $symlink_count); do
7637                         ln -s "$file1" "$dir/slink$s" ||
7638                                 error "cannot create symlinks"
7639                 done
7640                 echo "done"
7641
7642                 echo -n "creating nonlinked files..."
7643                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7644                         error "cannot create nonlinked files"
7645                 echo "done"
7646         fi
7647
7648         # create hard links
7649         if [ ! -f "$dir/file$total_count" ]; then
7650                 echo -n "creating hard links $begin:$total_count..."
7651                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7652                         /dev/null || error "cannot create hard links"
7653                 echo "done"
7654         fi
7655
7656         echo -n "checking number of hard links listed in xattrs..."
7657         local fid=$($LFS getstripe -F "$file1")
7658         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7659
7660         echo "${#paths[*]}"
7661         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7662                         skip "hard link list has unexpected size, skipping test"
7663         fi
7664         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7665                         error "link names should exceed xattrs size"
7666         fi
7667
7668         echo -n "migrating files..."
7669         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7670         local rc=$?
7671         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7672         echo "done"
7673
7674         # make sure all links have been properly migrated
7675         echo -n "verifying files..."
7676         fid=$($LFS getstripe -F "$file1") ||
7677                 error "cannot get fid for file $file1"
7678         for i in $(seq 2 $total_count); do
7679                 local fid2=$($LFS getstripe -F $dir/file$i)
7680
7681                 [ "$fid2" == "$fid" ] ||
7682                         error "migrated hard link has mismatched FID"
7683         done
7684
7685         # make sure hard links were properly detected, and migration was
7686         # performed only once for the entire link set; nonlinked files should
7687         # also be migrated
7688         local actual=$(grep -c 'done' <<< "$migrate_out")
7689         local expected=$(($uniq_count + 1))
7690
7691         [ "$actual" -eq  "$expected" ] ||
7692                 error "hard links individually migrated ($actual != $expected)"
7693
7694         # make sure the correct number of hard links are present
7695         local hardlinks=$(stat -c '%h' "$file1")
7696
7697         [ $hardlinks -eq $total_count ] ||
7698                 error "num hard links $hardlinks != $total_count"
7699         echo "done"
7700
7701         return 0
7702 }
7703
7704 test_56xb() {
7705         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7706                 skip "Need MDS version at least 2.10.55"
7707
7708         local dir="$DIR/$tdir"
7709
7710         test_mkdir "$dir" || error "cannot create dir $dir"
7711
7712         echo "testing lfs migrate mode when all links fit within xattrs"
7713         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7714
7715         echo "testing rsync mode when all links fit within xattrs"
7716         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7717
7718         echo "testing lfs migrate mode when all links do not fit within xattrs"
7719         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7720
7721         echo "testing rsync mode when all links do not fit within xattrs"
7722         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7723
7724         chown -R $RUNAS_ID $dir
7725         echo "testing non-root lfs migrate mode when not all links are in xattr"
7726         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7727
7728         # clean up
7729         rm -rf $dir
7730 }
7731 run_test 56xb "lfs migration hard link support"
7732
7733 test_56xc() {
7734         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7735
7736         local dir="$DIR/$tdir"
7737
7738         test_mkdir "$dir" || error "cannot create dir $dir"
7739
7740         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7741         echo -n "Setting initial stripe for 20MB test file..."
7742         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7743                 error "cannot setstripe 20MB file"
7744         echo "done"
7745         echo -n "Sizing 20MB test file..."
7746         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7747         echo "done"
7748         echo -n "Verifying small file autostripe count is 1..."
7749         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7750                 error "cannot migrate 20MB file"
7751         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7752                 error "cannot get stripe for $dir/20mb"
7753         [ $stripe_count -eq 1 ] ||
7754                 error "unexpected stripe count $stripe_count for 20MB file"
7755         rm -f "$dir/20mb"
7756         echo "done"
7757
7758         # Test 2: File is small enough to fit within the available space on
7759         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7760         # have at least an additional 1KB for each desired stripe for test 3
7761         echo -n "Setting stripe for 1GB test file..."
7762         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7763         echo "done"
7764         echo -n "Sizing 1GB test file..."
7765         # File size is 1GB + 3KB
7766         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7767         echo "done"
7768
7769         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7770         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7771         if (( avail > 524288 * OSTCOUNT )); then
7772                 echo -n "Migrating 1GB file..."
7773                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7774                         error "cannot migrate 1GB file"
7775                 echo "done"
7776                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7777                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7778                         error "cannot getstripe for 1GB file"
7779                 [ $stripe_count -eq 2 ] ||
7780                         error "unexpected stripe count $stripe_count != 2"
7781                 echo "done"
7782         fi
7783
7784         # Test 3: File is too large to fit within the available space on
7785         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7786         if [ $OSTCOUNT -ge 3 ]; then
7787                 # The required available space is calculated as
7788                 # file size (1GB + 3KB) / OST count (3).
7789                 local kb_per_ost=349526
7790
7791                 echo -n "Migrating 1GB file with limit..."
7792                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7793                         error "cannot migrate 1GB file with limit"
7794                 echo "done"
7795
7796                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7797                 echo -n "Verifying 1GB autostripe count with limited space..."
7798                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7799                         error "unexpected stripe count $stripe_count (min 3)"
7800                 echo "done"
7801         fi
7802
7803         # clean up
7804         rm -rf $dir
7805 }
7806 run_test 56xc "lfs migration autostripe"
7807
7808 test_56xd() {
7809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7810
7811         local dir=$DIR/$tdir
7812         local f_mgrt=$dir/$tfile.mgrt
7813         local f_yaml=$dir/$tfile.yaml
7814         local f_copy=$dir/$tfile.copy
7815         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7816         local layout_copy="-c 2 -S 2M -i 1"
7817         local yamlfile=$dir/yamlfile
7818         local layout_before;
7819         local layout_after;
7820
7821         test_mkdir "$dir" || error "cannot create dir $dir"
7822         $LFS setstripe $layout_yaml $f_yaml ||
7823                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7824         $LFS getstripe --yaml $f_yaml > $yamlfile
7825         $LFS setstripe $layout_copy $f_copy ||
7826                 error "cannot setstripe $f_copy with layout $layout_copy"
7827         touch $f_mgrt
7828         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7829
7830         # 1. test option --yaml
7831         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7832                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7833         layout_before=$(get_layout_param $f_yaml)
7834         layout_after=$(get_layout_param $f_mgrt)
7835         [ "$layout_after" == "$layout_before" ] ||
7836                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7837
7838         # 2. test option --copy
7839         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7840                 error "cannot migrate $f_mgrt with --copy $f_copy"
7841         layout_before=$(get_layout_param $f_copy)
7842         layout_after=$(get_layout_param $f_mgrt)
7843         [ "$layout_after" == "$layout_before" ] ||
7844                 error "lfs_migrate --copy: $layout_after != $layout_before"
7845 }
7846 run_test 56xd "check lfs_migrate --yaml and --copy support"
7847
7848 test_56xe() {
7849         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7850
7851         local dir=$DIR/$tdir
7852         local f_comp=$dir/$tfile
7853         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7854         local layout_before=""
7855         local layout_after=""
7856
7857         test_mkdir "$dir" || error "cannot create dir $dir"
7858         $LFS setstripe $layout $f_comp ||
7859                 error "cannot setstripe $f_comp with layout $layout"
7860         layout_before=$(get_layout_param $f_comp)
7861         dd if=/dev/zero of=$f_comp bs=1M count=4
7862
7863         # 1. migrate a comp layout file by lfs_migrate
7864         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7865         layout_after=$(get_layout_param $f_comp)
7866         [ "$layout_before" == "$layout_after" ] ||
7867                 error "lfs_migrate: $layout_before != $layout_after"
7868
7869         # 2. migrate a comp layout file by lfs migrate
7870         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7871         layout_after=$(get_layout_param $f_comp)
7872         [ "$layout_before" == "$layout_after" ] ||
7873                 error "lfs migrate: $layout_before != $layout_after"
7874 }
7875 run_test 56xe "migrate a composite layout file"
7876
7877 test_56xf() {
7878         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7879
7880         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7881                 skip "Need server version at least 2.13.53"
7882
7883         local dir=$DIR/$tdir
7884         local f_comp=$dir/$tfile
7885         local layout="-E 1M -c1 -E -1 -c2"
7886         local fid_before=""
7887         local fid_after=""
7888
7889         test_mkdir "$dir" || error "cannot create dir $dir"
7890         $LFS setstripe $layout $f_comp ||
7891                 error "cannot setstripe $f_comp with layout $layout"
7892         fid_before=$($LFS getstripe --fid $f_comp)
7893         dd if=/dev/zero of=$f_comp bs=1M count=4
7894
7895         # 1. migrate a comp layout file to a comp layout
7896         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7897         fid_after=$($LFS getstripe --fid $f_comp)
7898         [ "$fid_before" == "$fid_after" ] ||
7899                 error "comp-to-comp migrate: $fid_before != $fid_after"
7900
7901         # 2. migrate a comp layout file to a plain layout
7902         $LFS migrate -c2 $f_comp ||
7903                 error "cannot migrate $f_comp by lfs migrate"
7904         fid_after=$($LFS getstripe --fid $f_comp)
7905         [ "$fid_before" == "$fid_after" ] ||
7906                 error "comp-to-plain migrate: $fid_before != $fid_after"
7907
7908         # 3. migrate a plain layout file to a comp layout
7909         $LFS migrate $layout $f_comp ||
7910                 error "cannot migrate $f_comp by lfs migrate"
7911         fid_after=$($LFS getstripe --fid $f_comp)
7912         [ "$fid_before" == "$fid_after" ] ||
7913                 error "plain-to-comp migrate: $fid_before != $fid_after"
7914 }
7915 run_test 56xf "FID is not lost during migration of a composite layout file"
7916
7917 check_file_ost_range() {
7918         local file="$1"
7919         shift
7920         local range="$*"
7921         local -a file_range
7922         local idx
7923
7924         file_range=($($LFS getstripe -y "$file" |
7925                 awk '/l_ost_idx:/ { print $NF }'))
7926
7927         if [[ "${#file_range[@]}" = 0 ]]; then
7928                 echo "No osts found for $file"
7929                 return 1
7930         fi
7931
7932         for idx in "${file_range[@]}"; do
7933                 [[ " $range " =~ " $idx " ]] ||
7934                         return 1
7935         done
7936
7937         return 0
7938 }
7939
7940 sub_test_56xg() {
7941         local stripe_opt="$1"
7942         local pool="$2"
7943         shift 2
7944         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7945
7946         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7947                 error "Fail to migrate $tfile on $pool"
7948         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7949                 error "$tfile is not in pool $pool"
7950         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7951                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7952 }
7953
7954 test_56xg() {
7955         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7956         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7957         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7958                 skip "Need MDS version newer than 2.14.52"
7959
7960         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7961         local -a pool_ranges=("0 0" "1 1" "0 1")
7962
7963         # init pools
7964         for i in "${!pool_names[@]}"; do
7965                 pool_add ${pool_names[$i]} ||
7966                         error "pool_add failed (pool: ${pool_names[$i]})"
7967                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7968                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7969         done
7970
7971         # init the file to migrate
7972         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7973                 error "Unable to create $tfile on OST1"
7974         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7975                 error "Unable to write on $tfile"
7976
7977         echo "1. migrate $tfile on pool ${pool_names[0]}"
7978         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7979
7980         echo "2. migrate $tfile on pool ${pool_names[2]}"
7981         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7982
7983         echo "3. migrate $tfile on pool ${pool_names[1]}"
7984         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7985
7986         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7987         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7988         echo
7989
7990         # Clean pools
7991         destroy_test_pools ||
7992                 error "pool_destroy failed"
7993 }
7994 run_test 56xg "lfs migrate pool support"
7995
7996 test_56y() {
7997         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7998                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7999
8000         local res=""
8001         local dir=$DIR/$tdir
8002         local f1=$dir/file1
8003         local f2=$dir/file2
8004
8005         test_mkdir -p $dir || error "creating dir $dir"
8006         touch $f1 || error "creating std file $f1"
8007         $MULTIOP $f2 H2c || error "creating released file $f2"
8008
8009         # a directory can be raid0, so ask only for files
8010         res=$($LFS find $dir -L raid0 -type f | wc -l)
8011         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8012
8013         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8014         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8015
8016         # only files can be released, so no need to force file search
8017         res=$($LFS find $dir -L released)
8018         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8019
8020         res=$($LFS find $dir -type f \! -L released)
8021         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8022 }
8023 run_test 56y "lfs find -L raid0|released"
8024
8025 test_56z() { # LU-4824
8026         # This checks to make sure 'lfs find' continues after errors
8027         # There are two classes of errors that should be caught:
8028         # - If multiple paths are provided, all should be searched even if one
8029         #   errors out
8030         # - If errors are encountered during the search, it should not terminate
8031         #   early
8032         local dir=$DIR/$tdir
8033         local i
8034
8035         test_mkdir $dir
8036         for i in d{0..9}; do
8037                 test_mkdir $dir/$i
8038                 touch $dir/$i/$tfile
8039         done
8040         $LFS find $DIR/non_existent_dir $dir &&
8041                 error "$LFS find did not return an error"
8042         # Make a directory unsearchable. This should NOT be the last entry in
8043         # directory order.  Arbitrarily pick the 6th entry
8044         chmod 700 $($LFS find $dir -type d | sed '6!d')
8045
8046         $RUNAS $LFS find $DIR/non_existent $dir
8047         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8048
8049         # The user should be able to see 10 directories and 9 files
8050         (( count == 19 )) ||
8051                 error "$LFS find found $count != 19 entries after error"
8052 }
8053 run_test 56z "lfs find should continue after an error"
8054
8055 test_56aa() { # LU-5937
8056         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8057
8058         local dir=$DIR/$tdir
8059
8060         mkdir $dir
8061         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8062
8063         createmany -o $dir/striped_dir/${tfile}- 1024
8064         local dirs=$($LFS find --size +8k $dir/)
8065
8066         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8067 }
8068 run_test 56aa "lfs find --size under striped dir"
8069
8070 test_56ab() { # LU-10705
8071         test_mkdir $DIR/$tdir
8072         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8073         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8074         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8075         # Flush writes to ensure valid blocks.  Need to be more thorough for
8076         # ZFS, since blocks are not allocated/returned to client immediately.
8077         sync_all_data
8078         wait_zfs_commit ost1 2
8079         cancel_lru_locks osc
8080         ls -ls $DIR/$tdir
8081
8082         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8083
8084         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8085
8086         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8087         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8088
8089         rm -f $DIR/$tdir/$tfile.[123]
8090 }
8091 run_test 56ab "lfs find --blocks"
8092
8093 # LU-11188
8094 test_56aca() {
8095         local dir="$DIR/$tdir"
8096         local perms=(001 002 003 004 005 006 007
8097                      010 020 030 040 050 060 070
8098                      100 200 300 400 500 600 700
8099                      111 222 333 444 555 666 777)
8100         local perm_minus=(8 8 4 8 4 4 2
8101                           8 8 4 8 4 4 2
8102                           8 8 4 8 4 4 2
8103                           4 4 2 4 2 2 1)
8104         local perm_slash=(8  8 12  8 12 12 14
8105                           8  8 12  8 12 12 14
8106                           8  8 12  8 12 12 14
8107                          16 16 24 16 24 24 28)
8108
8109         test_mkdir "$dir"
8110         for perm in ${perms[*]}; do
8111                 touch "$dir/$tfile.$perm"
8112                 chmod $perm "$dir/$tfile.$perm"
8113         done
8114
8115         for ((i = 0; i < ${#perms[*]}; i++)); do
8116                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8117                 (( $num == 1 )) ||
8118                         error "lfs find -perm ${perms[i]}:"\
8119                               "$num != 1"
8120
8121                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8122                 (( $num == ${perm_minus[i]} )) ||
8123                         error "lfs find -perm -${perms[i]}:"\
8124                               "$num != ${perm_minus[i]}"
8125
8126                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8127                 (( $num == ${perm_slash[i]} )) ||
8128                         error "lfs find -perm /${perms[i]}:"\
8129                               "$num != ${perm_slash[i]}"
8130         done
8131 }
8132 run_test 56aca "check lfs find -perm with octal representation"
8133
8134 test_56acb() {
8135         local dir=$DIR/$tdir
8136         # p is the permission of write and execute for user, group and other
8137         # without the umask. It is used to test +wx.
8138         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8139         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8140         local symbolic=(+t  a+t u+t g+t o+t
8141                         g+s u+s o+s +s o+sr
8142                         o=r,ug+o,u+w
8143                         u+ g+ o+ a+ ugo+
8144                         u- g- o- a- ugo-
8145                         u= g= o= a= ugo=
8146                         o=r,ug+o,u+w u=r,a+u,u+w
8147                         g=r,ugo=g,u+w u+x,+X +X
8148                         u+x,u+X u+X u+x,g+X o+r,+X
8149                         u+x,go+X +wx +rwx)
8150
8151         test_mkdir $dir
8152         for perm in ${perms[*]}; do
8153                 touch "$dir/$tfile.$perm"
8154                 chmod $perm "$dir/$tfile.$perm"
8155         done
8156
8157         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8158                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8159
8160                 (( $num == 1 )) ||
8161                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8162         done
8163 }
8164 run_test 56acb "check lfs find -perm with symbolic representation"
8165
8166 test_56acc() {
8167         local dir=$DIR/$tdir
8168         local tests="17777 787 789 abcd
8169                 ug=uu ug=a ug=gu uo=ou urw
8170                 u+xg+x a=r,u+x,"
8171
8172         test_mkdir $dir
8173         for err in $tests; do
8174                 if $LFS find $dir -perm $err 2>/dev/null; then
8175                         error "lfs find -perm $err: parsing should have failed"
8176                 fi
8177         done
8178 }
8179 run_test 56acc "check parsing error for lfs find -perm"
8180
8181 test_56ba() {
8182         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8183                 skip "Need MDS version at least 2.10.50"
8184
8185         # Create composite files with one component
8186         local dir=$DIR/$tdir
8187
8188         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8189         # Create composite files with three components
8190         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8191         # Create non-composite files
8192         createmany -o $dir/${tfile}- 10
8193
8194         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8195
8196         [[ $nfiles == 10 ]] ||
8197                 error "lfs find -E 1M found $nfiles != 10 files"
8198
8199         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8200         [[ $nfiles == 25 ]] ||
8201                 error "lfs find ! -E 1M found $nfiles != 25 files"
8202
8203         # All files have a component that starts at 0
8204         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8205         [[ $nfiles == 35 ]] ||
8206                 error "lfs find --component-start 0 - $nfiles != 35 files"
8207
8208         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8209         [[ $nfiles == 15 ]] ||
8210                 error "lfs find --component-start 2M - $nfiles != 15 files"
8211
8212         # All files created here have a componenet that does not starts at 2M
8213         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8214         [[ $nfiles == 35 ]] ||
8215                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8216
8217         # Find files with a specified number of components
8218         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8219         [[ $nfiles == 15 ]] ||
8220                 error "lfs find --component-count 3 - $nfiles != 15 files"
8221
8222         # Remember non-composite files have a component count of zero
8223         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8224         [[ $nfiles == 10 ]] ||
8225                 error "lfs find --component-count 0 - $nfiles != 10 files"
8226
8227         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8228         [[ $nfiles == 20 ]] ||
8229                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8230
8231         # All files have a flag called "init"
8232         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8233         [[ $nfiles == 35 ]] ||
8234                 error "lfs find --component-flags init - $nfiles != 35 files"
8235
8236         # Multi-component files will have a component not initialized
8237         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8238         [[ $nfiles == 15 ]] ||
8239                 error "lfs find !--component-flags init - $nfiles != 15 files"
8240
8241         rm -rf $dir
8242
8243 }
8244 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8245
8246 test_56ca() {
8247         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8248                 skip "Need MDS version at least 2.10.57"
8249
8250         local td=$DIR/$tdir
8251         local tf=$td/$tfile
8252         local dir
8253         local nfiles
8254         local cmd
8255         local i
8256         local j
8257
8258         # create mirrored directories and mirrored files
8259         mkdir $td || error "mkdir $td failed"
8260         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8261         createmany -o $tf- 10 || error "create $tf- failed"
8262
8263         for i in $(seq 2); do
8264                 dir=$td/dir$i
8265                 mkdir $dir || error "mkdir $dir failed"
8266                 $LFS mirror create -N$((3 + i)) $dir ||
8267                         error "create mirrored dir $dir failed"
8268                 createmany -o $dir/$tfile- 10 ||
8269                         error "create $dir/$tfile- failed"
8270         done
8271
8272         # change the states of some mirrored files
8273         echo foo > $tf-6
8274         for i in $(seq 2); do
8275                 dir=$td/dir$i
8276                 for j in $(seq 4 9); do
8277                         echo foo > $dir/$tfile-$j
8278                 done
8279         done
8280
8281         # find mirrored files with specific mirror count
8282         cmd="$LFS find --mirror-count 3 --type f $td"
8283         nfiles=$($cmd | wc -l)
8284         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8285
8286         cmd="$LFS find ! --mirror-count 3 --type f $td"
8287         nfiles=$($cmd | wc -l)
8288         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8289
8290         cmd="$LFS find --mirror-count +2 --type f $td"
8291         nfiles=$($cmd | wc -l)
8292         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8293
8294         cmd="$LFS find --mirror-count -6 --type f $td"
8295         nfiles=$($cmd | wc -l)
8296         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8297
8298         # find mirrored files with specific file state
8299         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8300         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8301
8302         cmd="$LFS find --mirror-state=ro --type f $td"
8303         nfiles=$($cmd | wc -l)
8304         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8305
8306         cmd="$LFS find ! --mirror-state=ro --type f $td"
8307         nfiles=$($cmd | wc -l)
8308         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8309
8310         cmd="$LFS find --mirror-state=wp --type f $td"
8311         nfiles=$($cmd | wc -l)
8312         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8313
8314         cmd="$LFS find ! --mirror-state=sp --type f $td"
8315         nfiles=$($cmd | wc -l)
8316         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8317 }
8318 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8319
8320 test_56da() { # LU-14179
8321         local path=$DIR/$tdir
8322
8323         test_mkdir $path
8324         cd $path
8325
8326         local longdir=$(str_repeat 'a' 255)
8327
8328         for i in {1..15}; do
8329                 path=$path/$longdir
8330                 test_mkdir $longdir
8331                 cd $longdir
8332         done
8333
8334         local len=${#path}
8335         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8336
8337         test_mkdir $lastdir
8338         cd $lastdir
8339         # PATH_MAX-1
8340         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8341
8342         # NAME_MAX
8343         touch $(str_repeat 'f' 255)
8344
8345         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8346                 error "lfs find reported an error"
8347
8348         rm -rf $DIR/$tdir
8349 }
8350 run_test 56da "test lfs find with long paths"
8351
8352 test_56ea() { #LU-10378
8353         local path=$DIR/$tdir
8354         local pool=$TESTNAME
8355
8356         # Create ost pool
8357         pool_add $pool || error "pool_add $pool failed"
8358         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8359                 error "adding targets to $pool failed"
8360
8361         # Set default pool on directory before creating file
8362         mkdir $path || error "mkdir $path failed"
8363         $LFS setstripe -p $pool $path ||
8364                 error "set OST pool on $pool failed"
8365         touch $path/$tfile || error "touch $path/$tfile failed"
8366
8367         # Compare basic file attributes from -printf and stat
8368         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8369         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8370
8371         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8372                 error "Attrs from lfs find and stat don't match"
8373
8374         # Compare Lustre attributes from lfs find and lfs getstripe
8375         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8376         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8377         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8378         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8379         local fpool=$($LFS getstripe --pool $path/$tfile)
8380         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8381
8382         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8383                 error "Attrs from lfs find and lfs getstripe don't match"
8384
8385         # Verify behavior for unknown escape/format sequences
8386         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8387
8388         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8389                 error "Escape/format codes don't match"
8390 }
8391 run_test 56ea "test lfs find -printf option"
8392
8393 test_57a() {
8394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8395         # note test will not do anything if MDS is not local
8396         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8397                 skip_env "ldiskfs only test"
8398         fi
8399         remote_mds_nodsh && skip "remote MDS with nodsh"
8400
8401         local MNTDEV="osd*.*MDT*.mntdev"
8402         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8403         [ -z "$DEV" ] && error "can't access $MNTDEV"
8404         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8405                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8406                         error "can't access $DEV"
8407                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8408                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8409                 rm $TMP/t57a.dump
8410         done
8411 }
8412 run_test 57a "verify MDS filesystem created with large inodes =="
8413
8414 test_57b() {
8415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8416         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8417                 skip_env "ldiskfs only test"
8418         fi
8419         remote_mds_nodsh && skip "remote MDS with nodsh"
8420
8421         local dir=$DIR/$tdir
8422         local filecount=100
8423         local file1=$dir/f1
8424         local fileN=$dir/f$filecount
8425
8426         rm -rf $dir || error "removing $dir"
8427         test_mkdir -c1 $dir
8428         local mdtidx=$($LFS getstripe -m $dir)
8429         local mdtname=MDT$(printf %04x $mdtidx)
8430         local facet=mds$((mdtidx + 1))
8431
8432         echo "mcreating $filecount files"
8433         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8434
8435         # verify that files do not have EAs yet
8436         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8437                 error "$file1 has an EA"
8438         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8439                 error "$fileN has an EA"
8440
8441         sync
8442         sleep 1
8443         df $dir  #make sure we get new statfs data
8444         local mdsfree=$(do_facet $facet \
8445                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8446         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8447         local file
8448
8449         echo "opening files to create objects/EAs"
8450         for file in $(seq -f $dir/f%g 1 $filecount); do
8451                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8452                         error "opening $file"
8453         done
8454
8455         # verify that files have EAs now
8456         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8457         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8458
8459         sleep 1  #make sure we get new statfs data
8460         df $dir
8461         local mdsfree2=$(do_facet $facet \
8462                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8463         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8464
8465         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8466                 if [ "$mdsfree" != "$mdsfree2" ]; then
8467                         error "MDC before $mdcfree != after $mdcfree2"
8468                 else
8469                         echo "MDC before $mdcfree != after $mdcfree2"
8470                         echo "unable to confirm if MDS has large inodes"
8471                 fi
8472         fi
8473         rm -rf $dir
8474 }
8475 run_test 57b "default LOV EAs are stored inside large inodes ==="
8476
8477 test_58() {
8478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8479         [ -z "$(which wiretest 2>/dev/null)" ] &&
8480                         skip_env "could not find wiretest"
8481
8482         wiretest
8483 }
8484 run_test 58 "verify cross-platform wire constants =============="
8485
8486 test_59() {
8487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8488
8489         echo "touch 130 files"
8490         createmany -o $DIR/f59- 130
8491         echo "rm 130 files"
8492         unlinkmany $DIR/f59- 130
8493         sync
8494         # wait for commitment of removal
8495         wait_delete_completed
8496 }
8497 run_test 59 "verify cancellation of llog records async ========="
8498
8499 TEST60_HEAD="test_60 run $RANDOM"
8500 test_60a() {
8501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8502         remote_mgs_nodsh && skip "remote MGS with nodsh"
8503         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8504                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8505                         skip_env "missing subtest run-llog.sh"
8506
8507         log "$TEST60_HEAD - from kernel mode"
8508         do_facet mgs "$LCTL dk > /dev/null"
8509         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8510         do_facet mgs $LCTL dk > $TMP/$tfile
8511
8512         # LU-6388: test llog_reader
8513         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8514         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8515         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8516                         skip_env "missing llog_reader"
8517         local fstype=$(facet_fstype mgs)
8518         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8519                 skip_env "Only for ldiskfs or zfs type mgs"
8520
8521         local mntpt=$(facet_mntpt mgs)
8522         local mgsdev=$(mgsdevname 1)
8523         local fid_list
8524         local fid
8525         local rec_list
8526         local rec
8527         local rec_type
8528         local obj_file
8529         local path
8530         local seq
8531         local oid
8532         local pass=true
8533
8534         #get fid and record list
8535         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8536                 tail -n 4))
8537         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8538                 tail -n 4))
8539         #remount mgs as ldiskfs or zfs type
8540         stop mgs || error "stop mgs failed"
8541         mount_fstype mgs || error "remount mgs failed"
8542         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8543                 fid=${fid_list[i]}
8544                 rec=${rec_list[i]}
8545                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8546                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8547                 oid=$((16#$oid))
8548
8549                 case $fstype in
8550                         ldiskfs )
8551                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8552                         zfs )
8553                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8554                 esac
8555                 echo "obj_file is $obj_file"
8556                 do_facet mgs $llog_reader $obj_file
8557
8558                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8559                         awk '{ print $3 }' | sed -e "s/^type=//g")
8560                 if [ $rec_type != $rec ]; then
8561                         echo "FAILED test_60a wrong record type $rec_type," \
8562                               "should be $rec"
8563                         pass=false
8564                         break
8565                 fi
8566
8567                 #check obj path if record type is LLOG_LOGID_MAGIC
8568                 if [ "$rec" == "1064553b" ]; then
8569                         path=$(do_facet mgs $llog_reader $obj_file |
8570                                 grep "path=" | awk '{ print $NF }' |
8571                                 sed -e "s/^path=//g")
8572                         if [ $obj_file != $mntpt/$path ]; then
8573                                 echo "FAILED test_60a wrong obj path" \
8574                                       "$montpt/$path, should be $obj_file"
8575                                 pass=false
8576                                 break
8577                         fi
8578                 fi
8579         done
8580         rm -f $TMP/$tfile
8581         #restart mgs before "error", otherwise it will block the next test
8582         stop mgs || error "stop mgs failed"
8583         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8584         $pass || error "test failed, see FAILED test_60a messages for specifics"
8585 }
8586 run_test 60a "llog_test run from kernel module and test llog_reader"
8587
8588 test_60b() { # bug 6411
8589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8590
8591         dmesg > $DIR/$tfile
8592         LLOG_COUNT=$(do_facet mgs dmesg |
8593                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8594                           /llog_[a-z]*.c:[0-9]/ {
8595                                 if (marker)
8596                                         from_marker++
8597                                 from_begin++
8598                           }
8599                           END {
8600                                 if (marker)
8601                                         print from_marker
8602                                 else
8603                                         print from_begin
8604                           }")
8605
8606         [[ $LLOG_COUNT -gt 120 ]] &&
8607                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8608 }
8609 run_test 60b "limit repeated messages from CERROR/CWARN"
8610
8611 test_60c() {
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613
8614         echo "create 5000 files"
8615         createmany -o $DIR/f60c- 5000
8616 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8617         lctl set_param fail_loc=0x80000137
8618         unlinkmany $DIR/f60c- 5000
8619         lctl set_param fail_loc=0
8620 }
8621 run_test 60c "unlink file when mds full"
8622
8623 test_60d() {
8624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8625
8626         SAVEPRINTK=$(lctl get_param -n printk)
8627         # verify "lctl mark" is even working"
8628         MESSAGE="test message ID $RANDOM $$"
8629         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8630         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8631
8632         lctl set_param printk=0 || error "set lnet.printk failed"
8633         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8634         MESSAGE="new test message ID $RANDOM $$"
8635         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8636         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8637         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8638
8639         lctl set_param -n printk="$SAVEPRINTK"
8640 }
8641 run_test 60d "test printk console message masking"
8642
8643 test_60e() {
8644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8645         remote_mds_nodsh && skip "remote MDS with nodsh"
8646
8647         touch $DIR/$tfile
8648 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8649         do_facet mds1 lctl set_param fail_loc=0x15b
8650         rm $DIR/$tfile
8651 }
8652 run_test 60e "no space while new llog is being created"
8653
8654 test_60f() {
8655         local old_path=$($LCTL get_param -n debug_path)
8656
8657         stack_trap "$LCTL set_param debug_path=$old_path"
8658         stack_trap "rm -f $TMP/$tfile*"
8659         rm -f $TMP/$tfile* 2> /dev/null
8660         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8661         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8662         test_mkdir $DIR/$tdir
8663         # retry in case the open is cached and not released
8664         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8665                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8666                 sleep 0.1
8667         done
8668         ls $TMP/$tfile*
8669         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8670 }
8671 run_test 60f "change debug_path works"
8672
8673 test_60g() {
8674         local pid
8675         local i
8676
8677         test_mkdir -c $MDSCOUNT $DIR/$tdir
8678
8679         (
8680                 local index=0
8681                 while true; do
8682                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8683                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8684                                 2>/dev/null
8685                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8686                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8687                         index=$((index + 1))
8688                 done
8689         ) &
8690
8691         pid=$!
8692
8693         for i in {0..100}; do
8694                 # define OBD_FAIL_OSD_TXN_START    0x19a
8695                 local index=$((i % MDSCOUNT + 1))
8696
8697                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8698                         > /dev/null
8699                 sleep 0.01
8700         done
8701
8702         kill -9 $pid
8703
8704         for i in $(seq $MDSCOUNT); do
8705                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8706         done
8707
8708         mkdir $DIR/$tdir/new || error "mkdir failed"
8709         rmdir $DIR/$tdir/new || error "rmdir failed"
8710
8711         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8712                 -t namespace
8713         for i in $(seq $MDSCOUNT); do
8714                 wait_update_facet mds$i "$LCTL get_param -n \
8715                         mdd.$(facet_svc mds$i).lfsck_namespace |
8716                         awk '/^status/ { print \\\$2 }'" "completed"
8717         done
8718
8719         ls -R $DIR/$tdir
8720         rm -rf $DIR/$tdir || error "rmdir failed"
8721 }
8722 run_test 60g "transaction abort won't cause MDT hung"
8723
8724 test_60h() {
8725         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8726                 skip "Need MDS version at least 2.12.52"
8727         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8728
8729         local f
8730
8731         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8732         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8733         for fail_loc in 0x80000188 0x80000189; do
8734                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8735                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8736                         error "mkdir $dir-$fail_loc failed"
8737                 for i in {0..10}; do
8738                         # create may fail on missing stripe
8739                         echo $i > $DIR/$tdir-$fail_loc/$i
8740                 done
8741                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8742                         error "getdirstripe $tdir-$fail_loc failed"
8743                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8744                         error "migrate $tdir-$fail_loc failed"
8745                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8746                         error "getdirstripe $tdir-$fail_loc failed"
8747                 pushd $DIR/$tdir-$fail_loc
8748                 for f in *; do
8749                         echo $f | cmp $f - || error "$f data mismatch"
8750                 done
8751                 popd
8752                 rm -rf $DIR/$tdir-$fail_loc
8753         done
8754 }
8755 run_test 60h "striped directory with missing stripes can be accessed"
8756
8757 function t60i_load() {
8758         mkdir $DIR/$tdir
8759         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8760         $LCTL set_param fail_loc=0x131c fail_val=1
8761         for ((i=0; i<5000; i++)); do
8762                 touch $DIR/$tdir/f$i
8763         done
8764 }
8765
8766 test_60i() {
8767         changelog_register || error "changelog_register failed"
8768         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8769         changelog_users $SINGLEMDS | grep -q $cl_user ||
8770                 error "User $cl_user not found in changelog_users"
8771         changelog_chmask "ALL"
8772         t60i_load &
8773         local PID=$!
8774         for((i=0; i<100; i++)); do
8775                 changelog_dump >/dev/null ||
8776                         error "can't read changelog"
8777         done
8778         kill $PID
8779         wait $PID
8780         changelog_deregister || error "changelog_deregister failed"
8781         $LCTL set_param fail_loc=0
8782 }
8783 run_test 60i "llog: new record vs reader race"
8784
8785 test_61a() {
8786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8787
8788         f="$DIR/f61"
8789         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8790         cancel_lru_locks osc
8791         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8792         sync
8793 }
8794 run_test 61a "mmap() writes don't make sync hang ================"
8795
8796 test_61b() {
8797         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8798 }
8799 run_test 61b "mmap() of unstriped file is successful"
8800
8801 # bug 2330 - insufficient obd_match error checking causes LBUG
8802 test_62() {
8803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8804
8805         f="$DIR/f62"
8806         echo foo > $f
8807         cancel_lru_locks osc
8808         lctl set_param fail_loc=0x405
8809         cat $f && error "cat succeeded, expect -EIO"
8810         lctl set_param fail_loc=0
8811 }
8812 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8813 # match every page all of the time.
8814 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8815
8816 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8817 # Though this test is irrelevant anymore, it helped to reveal some
8818 # other grant bugs (LU-4482), let's keep it.
8819 test_63a() {   # was test_63
8820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8821
8822         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8823
8824         for i in `seq 10` ; do
8825                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8826                 sleep 5
8827                 kill $!
8828                 sleep 1
8829         done
8830
8831         rm -f $DIR/f63 || true
8832 }
8833 run_test 63a "Verify oig_wait interruption does not crash ======="
8834
8835 # bug 2248 - async write errors didn't return to application on sync
8836 # bug 3677 - async write errors left page locked
8837 test_63b() {
8838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8839
8840         debugsave
8841         lctl set_param debug=-1
8842
8843         # ensure we have a grant to do async writes
8844         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8845         rm $DIR/$tfile
8846
8847         sync    # sync lest earlier test intercept the fail_loc
8848
8849         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8850         lctl set_param fail_loc=0x80000406
8851         $MULTIOP $DIR/$tfile Owy && \
8852                 error "sync didn't return ENOMEM"
8853         sync; sleep 2; sync     # do a real sync this time to flush page
8854         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8855                 error "locked page left in cache after async error" || true
8856         debugrestore
8857 }
8858 run_test 63b "async write errors should be returned to fsync ==="
8859
8860 test_64a () {
8861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8862
8863         lfs df $DIR
8864         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8865 }
8866 run_test 64a "verify filter grant calculations (in kernel) ====="
8867
8868 test_64b () {
8869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8870
8871         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8872 }
8873 run_test 64b "check out-of-space detection on client"
8874
8875 test_64c() {
8876         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8877 }
8878 run_test 64c "verify grant shrink"
8879
8880 import_param() {
8881         local tgt=$1
8882         local param=$2
8883
8884         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8885 }
8886
8887 # this does exactly what osc_request.c:osc_announce_cached() does in
8888 # order to calculate max amount of grants to ask from server
8889 want_grant() {
8890         local tgt=$1
8891
8892         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8893         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8894
8895         ((rpc_in_flight++));
8896         nrpages=$((nrpages * rpc_in_flight))
8897
8898         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8899
8900         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8901
8902         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8903         local undirty=$((nrpages * PAGE_SIZE))
8904
8905         local max_extent_pages
8906         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8907         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8908         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8909         local grant_extent_tax
8910         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8911
8912         undirty=$((undirty + nrextents * grant_extent_tax))
8913
8914         echo $undirty
8915 }
8916
8917 # this is size of unit for grant allocation. It should be equal to
8918 # what tgt_grant.c:tgt_grant_chunk() calculates
8919 grant_chunk() {
8920         local tgt=$1
8921         local max_brw_size
8922         local grant_extent_tax
8923
8924         max_brw_size=$(import_param $tgt max_brw_size)
8925
8926         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8927
8928         echo $(((max_brw_size + grant_extent_tax) * 2))
8929 }
8930
8931 test_64d() {
8932         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8933                 skip "OST < 2.10.55 doesn't limit grants enough"
8934
8935         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8936
8937         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8938                 skip "no grant_param connect flag"
8939
8940         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8941
8942         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8943         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8944
8945
8946         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8947         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8948
8949         $LFS setstripe $DIR/$tfile -i 0 -c 1
8950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8951         ddpid=$!
8952
8953         while kill -0 $ddpid; do
8954                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8955
8956                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8957                         kill $ddpid
8958                         error "cur_grant $cur_grant > $max_cur_granted"
8959                 fi
8960
8961                 sleep 1
8962         done
8963 }
8964 run_test 64d "check grant limit exceed"
8965
8966 check_grants() {
8967         local tgt=$1
8968         local expected=$2
8969         local msg=$3
8970         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8971
8972         ((cur_grants == expected)) ||
8973                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8974 }
8975
8976 round_up_p2() {
8977         echo $((($1 + $2 - 1) & ~($2 - 1)))
8978 }
8979
8980 test_64e() {
8981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8982         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8983                 skip "Need OSS version at least 2.11.56"
8984
8985         # Remount client to reset grant
8986         remount_client $MOUNT || error "failed to remount client"
8987         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8988
8989         local init_grants=$(import_param $osc_tgt initial_grant)
8990
8991         check_grants $osc_tgt $init_grants "init grants"
8992
8993         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8994         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8995         local gbs=$(import_param $osc_tgt grant_block_size)
8996
8997         # write random number of bytes from max_brw_size / 4 to max_brw_size
8998         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8999         # align for direct io
9000         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9001         # round to grant consumption unit
9002         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9003
9004         local grants=$((wb_round_up + extent_tax))
9005
9006         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9007
9008         # define OBD_FAIL_TGT_NO_GRANT 0x725
9009         # make the server not grant more back
9010         do_facet ost1 $LCTL set_param fail_loc=0x725
9011         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9012
9013         do_facet ost1 $LCTL set_param fail_loc=0
9014
9015         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9016
9017         rm -f $DIR/$tfile || error "rm failed"
9018
9019         # Remount client to reset grant
9020         remount_client $MOUNT || error "failed to remount client"
9021         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9022
9023         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9024
9025         # define OBD_FAIL_TGT_NO_GRANT 0x725
9026         # make the server not grant more back
9027         do_facet ost1 $LCTL set_param fail_loc=0x725
9028         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9029         do_facet ost1 $LCTL set_param fail_loc=0
9030
9031         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9032 }
9033 run_test 64e "check grant consumption (no grant allocation)"
9034
9035 test_64f() {
9036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9037
9038         # Remount client to reset grant
9039         remount_client $MOUNT || error "failed to remount client"
9040         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9041
9042         local init_grants=$(import_param $osc_tgt initial_grant)
9043         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9044         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9045         local gbs=$(import_param $osc_tgt grant_block_size)
9046         local chunk=$(grant_chunk $osc_tgt)
9047
9048         # write random number of bytes from max_brw_size / 4 to max_brw_size
9049         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9050         # align for direct io
9051         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9052         # round to grant consumption unit
9053         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9054
9055         local grants=$((wb_round_up + extent_tax))
9056
9057         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9058         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9059                 error "error writing to $DIR/$tfile"
9060
9061         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9062                 "direct io with grant allocation"
9063
9064         rm -f $DIR/$tfile || error "rm failed"
9065
9066         # Remount client to reset grant
9067         remount_client $MOUNT || error "failed to remount client"
9068         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9069
9070         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9071
9072         local cmd="oO_WRONLY:w${write_bytes}_yc"
9073
9074         $MULTIOP $DIR/$tfile $cmd &
9075         MULTIPID=$!
9076         sleep 1
9077
9078         check_grants $osc_tgt $((init_grants - grants)) \
9079                 "buffered io, not write rpc"
9080
9081         kill -USR1 $MULTIPID
9082         wait
9083
9084         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9085                 "buffered io, one RPC"
9086 }
9087 run_test 64f "check grant consumption (with grant allocation)"
9088
9089 test_64g() {
9090         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9091                 skip "Need MDS version at least 2.14.56"
9092
9093         local mdts=$(comma_list $(mdts_nodes))
9094
9095         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9096                         tr '\n' ' ')
9097         stack_trap "$LCTL set_param $old"
9098
9099         # generate dirty pages and increase dirty granted on MDT
9100         stack_trap "rm -f $DIR/$tfile-*"
9101         for (( i = 0; i < 10; i++)); do
9102                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9103                         error "can't set stripe"
9104                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9105                         error "can't dd"
9106                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9107                         $LFS getstripe $DIR/$tfile-$i
9108                         error "not DoM file"
9109                 }
9110         done
9111
9112         # flush dirty pages
9113         sync
9114
9115         # wait until grant shrink reset grant dirty on MDTs
9116         for ((i = 0; i < 120; i++)); do
9117                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9118                         awk '{sum=sum+$1} END {print sum}')
9119                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9120                 echo "$grant_dirty grants, $vm_dirty pages"
9121                 (( grant_dirty + vm_dirty == 0 )) && break
9122                 (( i == 3 )) && sync &&
9123                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9124                 sleep 1
9125         done
9126
9127         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9128                 awk '{sum=sum+$1} END {print sum}')
9129         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9130 }
9131 run_test 64g "grant shrink on MDT"
9132
9133 test_64h() {
9134         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9135                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9136
9137         local instance=$($LFS getname -i $DIR)
9138         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9139         local num_exps=$(do_facet ost1 \
9140             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9141         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9142         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9143         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9144
9145         # 10MiB is for file to be written, max_brw_size * 16 *
9146         # num_exps is space reserve so that tgt_grant_shrink() decided
9147         # to not shrink
9148         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9149         (( avail * 1024 < expect )) &&
9150                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9151
9152         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9153         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9154         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9155         $LCTL set_param osc.*OST0000*.grant_shrink=1
9156         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9157
9158         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9159         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9160
9161         # drop cache so that coming read would do rpc
9162         cancel_lru_locks osc
9163
9164         # shrink interval is set to 10, pause for 7 seconds so that
9165         # grant thread did not wake up yet but coming read entered
9166         # shrink mode for rpc (osc_should_shrink_grant())
9167         sleep 7
9168
9169         declare -a cur_grant_bytes
9170         declare -a tot_granted
9171         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9172         tot_granted[0]=$(do_facet ost1 \
9173             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9174
9175         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9176
9177         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9178         tot_granted[1]=$(do_facet ost1 \
9179             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9180
9181         # grant change should be equal on both sides
9182         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9183                 tot_granted[0] - tot_granted[1])) ||
9184                 error "grant change mismatch, "                                \
9185                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9186                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9187 }
9188 run_test 64h "grant shrink on read"
9189
9190 test_64i() {
9191         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9192                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9193
9194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9195         remote_ost_nodsh && skip "remote OSTs with nodsh"
9196
9197         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9198
9199         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9200
9201         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9202         local instance=$($LFS getname -i $DIR)
9203
9204         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9205         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9206
9207         # shrink grants and simulate rpc loss
9208         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9209         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9210         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9211
9212         fail ost1
9213
9214         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9215
9216         local testid=$(echo $TESTNAME | tr '_' ' ')
9217
9218         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9219                 grep "GRANT, real grant" &&
9220                 error "client has more grants then it owns" || true
9221 }
9222 run_test 64i "shrink on reconnect"
9223
9224 # bug 1414 - set/get directories' stripe info
9225 test_65a() {
9226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9227
9228         test_mkdir $DIR/$tdir
9229         touch $DIR/$tdir/f1
9230         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9231 }
9232 run_test 65a "directory with no stripe info"
9233
9234 test_65b() {
9235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9236
9237         test_mkdir $DIR/$tdir
9238         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9239
9240         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9241                                                 error "setstripe"
9242         touch $DIR/$tdir/f2
9243         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9244 }
9245 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9246
9247 test_65c() {
9248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9249         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9250
9251         test_mkdir $DIR/$tdir
9252         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9253
9254         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9255                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9256         touch $DIR/$tdir/f3
9257         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9258 }
9259 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9260
9261 test_65d() {
9262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9263
9264         test_mkdir $DIR/$tdir
9265         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9266         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9267
9268         if [[ $STRIPECOUNT -le 0 ]]; then
9269                 sc=1
9270         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9271                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9272                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9273         else
9274                 sc=$(($STRIPECOUNT - 1))
9275         fi
9276         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9277         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9278         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9279                 error "lverify failed"
9280 }
9281 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9282
9283 test_65e() {
9284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9285
9286         test_mkdir $DIR/$tdir
9287
9288         $LFS setstripe $DIR/$tdir || error "setstripe"
9289         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9290                                         error "no stripe info failed"
9291         touch $DIR/$tdir/f6
9292         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9293 }
9294 run_test 65e "directory setstripe defaults"
9295
9296 test_65f() {
9297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9298
9299         test_mkdir $DIR/${tdir}f
9300         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9301                 error "setstripe succeeded" || true
9302 }
9303 run_test 65f "dir setstripe permission (should return error) ==="
9304
9305 test_65g() {
9306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9307
9308         test_mkdir $DIR/$tdir
9309         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9310
9311         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9312                 error "setstripe -S failed"
9313         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9314         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9315                 error "delete default stripe failed"
9316 }
9317 run_test 65g "directory setstripe -d"
9318
9319 test_65h() {
9320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9321
9322         test_mkdir $DIR/$tdir
9323         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9324
9325         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9326                 error "setstripe -S failed"
9327         test_mkdir $DIR/$tdir/dd1
9328         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9329                 error "stripe info inherit failed"
9330 }
9331 run_test 65h "directory stripe info inherit ===================="
9332
9333 test_65i() {
9334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9335
9336         save_layout_restore_at_exit $MOUNT
9337
9338         # bug6367: set non-default striping on root directory
9339         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9340
9341         # bug12836: getstripe on -1 default directory striping
9342         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9343
9344         # bug12836: getstripe -v on -1 default directory striping
9345         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9346
9347         # bug12836: new find on -1 default directory striping
9348         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9349 }
9350 run_test 65i "various tests to set root directory striping"
9351
9352 test_65j() { # bug6367
9353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9354
9355         sync; sleep 1
9356
9357         # if we aren't already remounting for each test, do so for this test
9358         if [ "$I_MOUNTED" = "yes" ]; then
9359                 cleanup || error "failed to unmount"
9360                 setup
9361         fi
9362
9363         save_layout_restore_at_exit $MOUNT
9364
9365         $LFS setstripe -d $MOUNT || error "setstripe failed"
9366 }
9367 run_test 65j "set default striping on root directory (bug 6367)="
9368
9369 cleanup_65k() {
9370         rm -rf $DIR/$tdir
9371         wait_delete_completed
9372         do_facet $SINGLEMDS "lctl set_param -n \
9373                 osp.$ost*MDT0000.max_create_count=$max_count"
9374         do_facet $SINGLEMDS "lctl set_param -n \
9375                 osp.$ost*MDT0000.create_count=$count"
9376         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9377         echo $INACTIVE_OSC "is Activate"
9378
9379         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9380 }
9381
9382 test_65k() { # bug11679
9383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9384         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9385         remote_mds_nodsh && skip "remote MDS with nodsh"
9386
9387         local disable_precreate=true
9388         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9389                 disable_precreate=false
9390
9391         echo "Check OST status: "
9392         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9393                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9394
9395         for OSC in $MDS_OSCS; do
9396                 echo $OSC "is active"
9397                 do_facet $SINGLEMDS lctl --device %$OSC activate
9398         done
9399
9400         for INACTIVE_OSC in $MDS_OSCS; do
9401                 local ost=$(osc_to_ost $INACTIVE_OSC)
9402                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9403                                lov.*md*.target_obd |
9404                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9405
9406                 mkdir -p $DIR/$tdir
9407                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9408                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9409
9410                 echo "Deactivate: " $INACTIVE_OSC
9411                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9412
9413                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9414                               osp.$ost*MDT0000.create_count")
9415                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9416                                   osp.$ost*MDT0000.max_create_count")
9417                 $disable_precreate &&
9418                         do_facet $SINGLEMDS "lctl set_param -n \
9419                                 osp.$ost*MDT0000.max_create_count=0"
9420
9421                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9422                         [ -f $DIR/$tdir/$idx ] && continue
9423                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9424                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9425                                 { cleanup_65k;
9426                                   error "setstripe $idx should succeed"; }
9427                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9428                 done
9429                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9430                 rmdir $DIR/$tdir
9431
9432                 do_facet $SINGLEMDS "lctl set_param -n \
9433                         osp.$ost*MDT0000.max_create_count=$max_count"
9434                 do_facet $SINGLEMDS "lctl set_param -n \
9435                         osp.$ost*MDT0000.create_count=$count"
9436                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9437                 echo $INACTIVE_OSC "is Activate"
9438
9439                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9440         done
9441 }
9442 run_test 65k "validate manual striping works properly with deactivated OSCs"
9443
9444 test_65l() { # bug 12836
9445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9446
9447         test_mkdir -p $DIR/$tdir/test_dir
9448         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9449         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9450 }
9451 run_test 65l "lfs find on -1 stripe dir ========================"
9452
9453 test_65m() {
9454         local layout=$(save_layout $MOUNT)
9455         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9456                 restore_layout $MOUNT $layout
9457                 error "setstripe should fail by non-root users"
9458         }
9459         true
9460 }
9461 run_test 65m "normal user can't set filesystem default stripe"
9462
9463 test_65n() {
9464         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9465         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9466                 skip "Need MDS version at least 2.12.50"
9467         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9468
9469         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9470         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9471         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9472
9473         save_layout_restore_at_exit $MOUNT
9474
9475         # new subdirectory under root directory should not inherit
9476         # the default layout from root
9477         local dir1=$MOUNT/$tdir-1
9478         mkdir $dir1 || error "mkdir $dir1 failed"
9479         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9480                 error "$dir1 shouldn't have LOV EA"
9481
9482         # delete the default layout on root directory
9483         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9484
9485         local dir2=$MOUNT/$tdir-2
9486         mkdir $dir2 || error "mkdir $dir2 failed"
9487         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9488                 error "$dir2 shouldn't have LOV EA"
9489
9490         # set a new striping pattern on root directory
9491         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9492         local new_def_stripe_size=$((def_stripe_size * 2))
9493         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9494                 error "set stripe size on $MOUNT failed"
9495
9496         # new file created in $dir2 should inherit the new stripe size from
9497         # the filesystem default
9498         local file2=$dir2/$tfile-2
9499         touch $file2 || error "touch $file2 failed"
9500
9501         local file2_stripe_size=$($LFS getstripe -S $file2)
9502         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9503         {
9504                 echo "file2_stripe_size: '$file2_stripe_size'"
9505                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9506                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9507         }
9508
9509         local dir3=$MOUNT/$tdir-3
9510         mkdir $dir3 || error "mkdir $dir3 failed"
9511         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9512         # the root layout, which is the actual default layout that will be used
9513         # when new files are created in $dir3.
9514         local dir3_layout=$(get_layout_param $dir3)
9515         local root_dir_layout=$(get_layout_param $MOUNT)
9516         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9517         {
9518                 echo "dir3_layout: '$dir3_layout'"
9519                 echo "root_dir_layout: '$root_dir_layout'"
9520                 error "$dir3 should show the default layout from $MOUNT"
9521         }
9522
9523         # set OST pool on root directory
9524         local pool=$TESTNAME
9525         pool_add $pool || error "add $pool failed"
9526         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9527                 error "add targets to $pool failed"
9528
9529         $LFS setstripe -p $pool $MOUNT ||
9530                 error "set OST pool on $MOUNT failed"
9531
9532         # new file created in $dir3 should inherit the pool from
9533         # the filesystem default
9534         local file3=$dir3/$tfile-3
9535         touch $file3 || error "touch $file3 failed"
9536
9537         local file3_pool=$($LFS getstripe -p $file3)
9538         [[ "$file3_pool" = "$pool" ]] ||
9539                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9540
9541         local dir4=$MOUNT/$tdir-4
9542         mkdir $dir4 || error "mkdir $dir4 failed"
9543         local dir4_layout=$(get_layout_param $dir4)
9544         root_dir_layout=$(get_layout_param $MOUNT)
9545         echo "$LFS getstripe -d $dir4"
9546         $LFS getstripe -d $dir4
9547         echo "$LFS getstripe -d $MOUNT"
9548         $LFS getstripe -d $MOUNT
9549         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9550         {
9551                 echo "dir4_layout: '$dir4_layout'"
9552                 echo "root_dir_layout: '$root_dir_layout'"
9553                 error "$dir4 should show the default layout from $MOUNT"
9554         }
9555
9556         # new file created in $dir4 should inherit the pool from
9557         # the filesystem default
9558         local file4=$dir4/$tfile-4
9559         touch $file4 || error "touch $file4 failed"
9560
9561         local file4_pool=$($LFS getstripe -p $file4)
9562         [[ "$file4_pool" = "$pool" ]] ||
9563                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9564
9565         # new subdirectory under non-root directory should inherit
9566         # the default layout from its parent directory
9567         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9568                 error "set directory layout on $dir4 failed"
9569
9570         local dir5=$dir4/$tdir-5
9571         mkdir $dir5 || error "mkdir $dir5 failed"
9572
9573         dir4_layout=$(get_layout_param $dir4)
9574         local dir5_layout=$(get_layout_param $dir5)
9575         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9576         {
9577                 echo "dir4_layout: '$dir4_layout'"
9578                 echo "dir5_layout: '$dir5_layout'"
9579                 error "$dir5 should inherit the default layout from $dir4"
9580         }
9581
9582         # though subdir under ROOT doesn't inherit default layout, but
9583         # its sub dir/file should be created with default layout.
9584         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9585         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9586                 skip "Need MDS version at least 2.12.59"
9587
9588         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9589         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9590         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9591
9592         if [ $default_lmv_hash == "none" ]; then
9593                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9594         else
9595                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9596                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9597         fi
9598
9599         $LFS setdirstripe -D -c 2 $MOUNT ||
9600                 error "setdirstripe -D -c 2 failed"
9601         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9602         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9603         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9604
9605         # $dir4 layout includes pool
9606         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9607         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9608                 error "pool lost on setstripe"
9609         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9610         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9611                 error "pool lost on compound layout setstripe"
9612 }
9613 run_test 65n "don't inherit default layout from root for new subdirectories"
9614
9615 # bug 2543 - update blocks count on client
9616 test_66() {
9617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9618
9619         COUNT=${COUNT:-8}
9620         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9621         sync; sync_all_data; sync; sync_all_data
9622         cancel_lru_locks osc
9623         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9624         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9625 }
9626 run_test 66 "update inode blocks count on client ==============="
9627
9628 meminfo() {
9629         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9630 }
9631
9632 swap_used() {
9633         swapon -s | awk '($1 == "'$1'") { print $4 }'
9634 }
9635
9636 # bug5265, obdfilter oa2dentry return -ENOENT
9637 # #define OBD_FAIL_SRV_ENOENT 0x217
9638 test_69() {
9639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9640         remote_ost_nodsh && skip "remote OST with nodsh"
9641
9642         f="$DIR/$tfile"
9643         $LFS setstripe -c 1 -i 0 $f
9644
9645         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9646
9647         do_facet ost1 lctl set_param fail_loc=0x217
9648         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9649         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9650
9651         do_facet ost1 lctl set_param fail_loc=0
9652         $DIRECTIO write $f 0 2 || error "write error"
9653
9654         cancel_lru_locks osc
9655         $DIRECTIO read $f 0 1 || error "read error"
9656
9657         do_facet ost1 lctl set_param fail_loc=0x217
9658         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9659
9660         do_facet ost1 lctl set_param fail_loc=0
9661         rm -f $f
9662 }
9663 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9664
9665 test_71() {
9666         test_mkdir $DIR/$tdir
9667         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9668         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9669 }
9670 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9671
9672 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9674         [ "$RUNAS_ID" = "$UID" ] &&
9675                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9676         # Check that testing environment is properly set up. Skip if not
9677         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9678                 skip_env "User $RUNAS_ID does not exist - skipping"
9679
9680         touch $DIR/$tfile
9681         chmod 777 $DIR/$tfile
9682         chmod ug+s $DIR/$tfile
9683         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9684                 error "$RUNAS dd $DIR/$tfile failed"
9685         # See if we are still setuid/sgid
9686         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9687                 error "S/gid is not dropped on write"
9688         # Now test that MDS is updated too
9689         cancel_lru_locks mdc
9690         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9691                 error "S/gid is not dropped on MDS"
9692         rm -f $DIR/$tfile
9693 }
9694 run_test 72a "Test that remove suid works properly (bug5695) ===="
9695
9696 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9697         local perm
9698
9699         [ "$RUNAS_ID" = "$UID" ] &&
9700                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9701         [ "$RUNAS_ID" -eq 0 ] &&
9702                 skip_env "RUNAS_ID = 0 -- skipping"
9703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9704         # Check that testing environment is properly set up. Skip if not
9705         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9706                 skip_env "User $RUNAS_ID does not exist - skipping"
9707
9708         touch $DIR/${tfile}-f{g,u}
9709         test_mkdir $DIR/${tfile}-dg
9710         test_mkdir $DIR/${tfile}-du
9711         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9712         chmod g+s $DIR/${tfile}-{f,d}g
9713         chmod u+s $DIR/${tfile}-{f,d}u
9714         for perm in 777 2777 4777; do
9715                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9716                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9717                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9718                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9719         done
9720         true
9721 }
9722 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9723
9724 # bug 3462 - multiple simultaneous MDC requests
9725 test_73() {
9726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9727
9728         test_mkdir $DIR/d73-1
9729         test_mkdir $DIR/d73-2
9730         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9731         pid1=$!
9732
9733         lctl set_param fail_loc=0x80000129
9734         $MULTIOP $DIR/d73-1/f73-2 Oc &
9735         sleep 1
9736         lctl set_param fail_loc=0
9737
9738         $MULTIOP $DIR/d73-2/f73-3 Oc &
9739         pid3=$!
9740
9741         kill -USR1 $pid1
9742         wait $pid1 || return 1
9743
9744         sleep 25
9745
9746         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9747         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9748         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9749
9750         rm -rf $DIR/d73-*
9751 }
9752 run_test 73 "multiple MDC requests (should not deadlock)"
9753
9754 test_74a() { # bug 6149, 6184
9755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9756
9757         touch $DIR/f74a
9758         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9759         #
9760         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9761         # will spin in a tight reconnection loop
9762         $LCTL set_param fail_loc=0x8000030e
9763         # get any lock that won't be difficult - lookup works.
9764         ls $DIR/f74a
9765         $LCTL set_param fail_loc=0
9766         rm -f $DIR/f74a
9767         true
9768 }
9769 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9770
9771 test_74b() { # bug 13310
9772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9773
9774         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9775         #
9776         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9777         # will spin in a tight reconnection loop
9778         $LCTL set_param fail_loc=0x8000030e
9779         # get a "difficult" lock
9780         touch $DIR/f74b
9781         $LCTL set_param fail_loc=0
9782         rm -f $DIR/f74b
9783         true
9784 }
9785 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9786
9787 test_74c() {
9788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9789
9790         #define OBD_FAIL_LDLM_NEW_LOCK
9791         $LCTL set_param fail_loc=0x319
9792         touch $DIR/$tfile && error "touch successful"
9793         $LCTL set_param fail_loc=0
9794         true
9795 }
9796 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9797
9798 slab_lic=/sys/kernel/slab/lustre_inode_cache
9799 num_objects() {
9800         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9801         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9802                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9803 }
9804
9805 test_76a() { # Now for b=20433, added originally in b=1443
9806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9807
9808         cancel_lru_locks osc
9809         # there may be some slab objects cached per core
9810         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9811         local before=$(num_objects)
9812         local count=$((512 * cpus))
9813         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9814         local margin=$((count / 10))
9815         if [[ -f $slab_lic/aliases ]]; then
9816                 local aliases=$(cat $slab_lic/aliases)
9817                 (( aliases > 0 )) && margin=$((margin * aliases))
9818         fi
9819
9820         echo "before slab objects: $before"
9821         for i in $(seq $count); do
9822                 touch $DIR/$tfile
9823                 rm -f $DIR/$tfile
9824         done
9825         cancel_lru_locks osc
9826         local after=$(num_objects)
9827         echo "created: $count, after slab objects: $after"
9828         # shared slab counts are not very accurate, allow significant margin
9829         # the main goal is that the cache growth is not permanently > $count
9830         while (( after > before + margin )); do
9831                 sleep 1
9832                 after=$(num_objects)
9833                 wait=$((wait + 1))
9834                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9835                 if (( wait > 60 )); then
9836                         error "inode slab grew from $before+$margin to $after"
9837                 fi
9838         done
9839 }
9840 run_test 76a "confirm clients recycle inodes properly ===="
9841
9842 test_76b() {
9843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9844         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9845
9846         local count=512
9847         local before=$(num_objects)
9848
9849         for i in $(seq $count); do
9850                 mkdir $DIR/$tdir
9851                 rmdir $DIR/$tdir
9852         done
9853
9854         local after=$(num_objects)
9855         local wait=0
9856
9857         while (( after > before )); do
9858                 sleep 1
9859                 after=$(num_objects)
9860                 wait=$((wait + 1))
9861                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9862                 if (( wait > 60 )); then
9863                         error "inode slab grew from $before to $after"
9864                 fi
9865         done
9866
9867         echo "slab objects before: $before, after: $after"
9868 }
9869 run_test 76b "confirm clients recycle directory inodes properly ===="
9870
9871 export ORIG_CSUM=""
9872 set_checksums()
9873 {
9874         # Note: in sptlrpc modes which enable its own bulk checksum, the
9875         # original crc32_le bulk checksum will be automatically disabled,
9876         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9877         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9878         # In this case set_checksums() will not be no-op, because sptlrpc
9879         # bulk checksum will be enabled all through the test.
9880
9881         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9882         lctl set_param -n osc.*.checksums $1
9883         return 0
9884 }
9885
9886 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9887                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9888 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9889                              tr -d [] | head -n1)}
9890 set_checksum_type()
9891 {
9892         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9893         rc=$?
9894         log "set checksum type to $1, rc = $rc"
9895         return $rc
9896 }
9897
9898 get_osc_checksum_type()
9899 {
9900         # arugment 1: OST name, like OST0000
9901         ost=$1
9902         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9903                         sed 's/.*\[\(.*\)\].*/\1/g')
9904         rc=$?
9905         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9906         echo $checksum_type
9907 }
9908
9909 F77_TMP=$TMP/f77-temp
9910 F77SZ=8
9911 setup_f77() {
9912         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9913                 error "error writing to $F77_TMP"
9914 }
9915
9916 test_77a() { # bug 10889
9917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9918         $GSS && skip_env "could not run with gss"
9919
9920         [ ! -f $F77_TMP ] && setup_f77
9921         set_checksums 1
9922         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9923         set_checksums 0
9924         rm -f $DIR/$tfile
9925 }
9926 run_test 77a "normal checksum read/write operation"
9927
9928 test_77b() { # bug 10889
9929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9930         $GSS && skip_env "could not run with gss"
9931
9932         [ ! -f $F77_TMP ] && setup_f77
9933         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9934         $LCTL set_param fail_loc=0x80000409
9935         set_checksums 1
9936
9937         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9938                 error "dd error: $?"
9939         $LCTL set_param fail_loc=0
9940
9941         for algo in $CKSUM_TYPES; do
9942                 cancel_lru_locks osc
9943                 set_checksum_type $algo
9944                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9945                 $LCTL set_param fail_loc=0x80000408
9946                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9947                 $LCTL set_param fail_loc=0
9948         done
9949         set_checksums 0
9950         set_checksum_type $ORIG_CSUM_TYPE
9951         rm -f $DIR/$tfile
9952 }
9953 run_test 77b "checksum error on client write, read"
9954
9955 cleanup_77c() {
9956         trap 0
9957         set_checksums 0
9958         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9959         $check_ost &&
9960                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9961         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9962         $check_ost && [ -n "$ost_file_prefix" ] &&
9963                 do_facet ost1 rm -f ${ost_file_prefix}\*
9964 }
9965
9966 test_77c() {
9967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9968         $GSS && skip_env "could not run with gss"
9969         remote_ost_nodsh && skip "remote OST with nodsh"
9970
9971         local bad1
9972         local osc_file_prefix
9973         local osc_file
9974         local check_ost=false
9975         local ost_file_prefix
9976         local ost_file
9977         local orig_cksum
9978         local dump_cksum
9979         local fid
9980
9981         # ensure corruption will occur on first OSS/OST
9982         $LFS setstripe -i 0 $DIR/$tfile
9983
9984         [ ! -f $F77_TMP ] && setup_f77
9985         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9986                 error "dd write error: $?"
9987         fid=$($LFS path2fid $DIR/$tfile)
9988
9989         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9990         then
9991                 check_ost=true
9992                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9993                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9994         else
9995                 echo "OSS do not support bulk pages dump upon error"
9996         fi
9997
9998         osc_file_prefix=$($LCTL get_param -n debug_path)
9999         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10000
10001         trap cleanup_77c EXIT
10002
10003         set_checksums 1
10004         # enable bulk pages dump upon error on Client
10005         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10006         # enable bulk pages dump upon error on OSS
10007         $check_ost &&
10008                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10009
10010         # flush Client cache to allow next read to reach OSS
10011         cancel_lru_locks osc
10012
10013         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10014         $LCTL set_param fail_loc=0x80000408
10015         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10016         $LCTL set_param fail_loc=0
10017
10018         rm -f $DIR/$tfile
10019
10020         # check cksum dump on Client
10021         osc_file=$(ls ${osc_file_prefix}*)
10022         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10023         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10024         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10025         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10026         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10027                      cksum)
10028         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10029         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10030                 error "dump content does not match on Client"
10031
10032         $check_ost || skip "No need to check cksum dump on OSS"
10033
10034         # check cksum dump on OSS
10035         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10036         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10037         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10038         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10039         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10040                 error "dump content does not match on OSS"
10041
10042         cleanup_77c
10043 }
10044 run_test 77c "checksum error on client read with debug"
10045
10046 test_77d() { # bug 10889
10047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10048         $GSS && skip_env "could not run with gss"
10049
10050         stack_trap "rm -f $DIR/$tfile"
10051         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10052         $LCTL set_param fail_loc=0x80000409
10053         set_checksums 1
10054         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10055                 error "direct write: rc=$?"
10056         $LCTL set_param fail_loc=0
10057         set_checksums 0
10058
10059         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10060         $LCTL set_param fail_loc=0x80000408
10061         set_checksums 1
10062         cancel_lru_locks osc
10063         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10064                 error "direct read: rc=$?"
10065         $LCTL set_param fail_loc=0
10066         set_checksums 0
10067 }
10068 run_test 77d "checksum error on OST direct write, read"
10069
10070 test_77f() { # bug 10889
10071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10072         $GSS && skip_env "could not run with gss"
10073
10074         set_checksums 1
10075         stack_trap "rm -f $DIR/$tfile"
10076         for algo in $CKSUM_TYPES; do
10077                 cancel_lru_locks osc
10078                 set_checksum_type $algo
10079                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10080                 $LCTL set_param fail_loc=0x409
10081                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10082                         error "direct write succeeded"
10083                 $LCTL set_param fail_loc=0
10084         done
10085         set_checksum_type $ORIG_CSUM_TYPE
10086         set_checksums 0
10087 }
10088 run_test 77f "repeat checksum error on write (expect error)"
10089
10090 test_77g() { # bug 10889
10091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10092         $GSS && skip_env "could not run with gss"
10093         remote_ost_nodsh && skip "remote OST with nodsh"
10094
10095         [ ! -f $F77_TMP ] && setup_f77
10096
10097         local file=$DIR/$tfile
10098         stack_trap "rm -f $file" EXIT
10099
10100         $LFS setstripe -c 1 -i 0 $file
10101         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10102         do_facet ost1 lctl set_param fail_loc=0x8000021a
10103         set_checksums 1
10104         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10105                 error "write error: rc=$?"
10106         do_facet ost1 lctl set_param fail_loc=0
10107         set_checksums 0
10108
10109         cancel_lru_locks osc
10110         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10111         do_facet ost1 lctl set_param fail_loc=0x8000021b
10112         set_checksums 1
10113         cmp $F77_TMP $file || error "file compare failed"
10114         do_facet ost1 lctl set_param fail_loc=0
10115         set_checksums 0
10116 }
10117 run_test 77g "checksum error on OST write, read"
10118
10119 test_77k() { # LU-10906
10120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10121         $GSS && skip_env "could not run with gss"
10122
10123         local cksum_param="osc.$FSNAME*.checksums"
10124         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10125         local checksum
10126         local i
10127
10128         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10129         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10130         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10131
10132         for i in 0 1; do
10133                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10134                         error "failed to set checksum=$i on MGS"
10135                 wait_update $HOSTNAME "$get_checksum" $i
10136                 #remount
10137                 echo "remount client, checksum should be $i"
10138                 remount_client $MOUNT || error "failed to remount client"
10139                 checksum=$(eval $get_checksum)
10140                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10141         done
10142         # remove persistent param to avoid races with checksum mountopt below
10143         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10144                 error "failed to delete checksum on MGS"
10145
10146         for opt in "checksum" "nochecksum"; do
10147                 #remount with mount option
10148                 echo "remount client with option $opt, checksum should be $i"
10149                 umount_client $MOUNT || error "failed to umount client"
10150                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10151                         error "failed to mount client with option '$opt'"
10152                 checksum=$(eval $get_checksum)
10153                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10154                 i=$((i - 1))
10155         done
10156
10157         remount_client $MOUNT || error "failed to remount client"
10158 }
10159 run_test 77k "enable/disable checksum correctly"
10160
10161 test_77l() {
10162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10163         $GSS && skip_env "could not run with gss"
10164
10165         set_checksums 1
10166         stack_trap "set_checksums $ORIG_CSUM" EXIT
10167         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10168
10169         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10170
10171         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10172         for algo in $CKSUM_TYPES; do
10173                 set_checksum_type $algo || error "fail to set checksum type $algo"
10174                 osc_algo=$(get_osc_checksum_type OST0000)
10175                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10176
10177                 # no locks, no reqs to let the connection idle
10178                 cancel_lru_locks osc
10179                 lru_resize_disable osc
10180                 wait_osc_import_state client ost1 IDLE
10181
10182                 # ensure ost1 is connected
10183                 stat $DIR/$tfile >/dev/null || error "can't stat"
10184                 wait_osc_import_state client ost1 FULL
10185
10186                 osc_algo=$(get_osc_checksum_type OST0000)
10187                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10188         done
10189         return 0
10190 }
10191 run_test 77l "preferred checksum type is remembered after reconnected"
10192
10193 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10194 rm -f $F77_TMP
10195 unset F77_TMP
10196
10197 test_77m() {
10198         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10199                 skip "Need at least version 2.14.52"
10200         local param=checksum_speed
10201
10202         $LCTL get_param $param || error "reading $param failed"
10203
10204         csum_speeds=$($LCTL get_param -n $param)
10205
10206         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10207                 error "known checksum types are missing"
10208 }
10209 run_test 77m "Verify checksum_speed is correctly read"
10210
10211 check_filefrag_77n() {
10212         local nr_ext=0
10213         local starts=()
10214         local ends=()
10215
10216         while read extidx a b start end rest; do
10217                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10218                         nr_ext=$(( $nr_ext + 1 ))
10219                         starts+=( ${start%..} )
10220                         ends+=( ${end%:} )
10221                 fi
10222         done < <( filefrag -sv $1 )
10223
10224         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10225         return 1
10226 }
10227
10228 test_77n() {
10229         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10230
10231         touch $DIR/$tfile
10232         $TRUNCATE $DIR/$tfile 0
10233         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10234         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10235         check_filefrag_77n $DIR/$tfile ||
10236                 skip "$tfile blocks not contiguous around hole"
10237
10238         set_checksums 1
10239         stack_trap "set_checksums $ORIG_CSUM" EXIT
10240         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10241         stack_trap "rm -f $DIR/$tfile"
10242
10243         for algo in $CKSUM_TYPES; do
10244                 if [[ "$algo" =~ ^t10 ]]; then
10245                         set_checksum_type $algo ||
10246                                 error "fail to set checksum type $algo"
10247                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10248                                 error "fail to read $tfile with $algo"
10249                 fi
10250         done
10251         rm -f $DIR/$tfile
10252         return 0
10253 }
10254 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10255
10256 test_77o() {
10257         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10258                 skip "Need MDS version at least 2.14.55"
10259         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10260                 skip "Need OST version at least 2.14.55"
10261         local ofd=obdfilter
10262         local mdt=mdt
10263
10264         # print OST checksum_type
10265         echo "$ofd.$FSNAME-*.checksum_type:"
10266         do_nodes $(comma_list $(osts_nodes)) \
10267                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10268
10269         # print MDT checksum_type
10270         echo "$mdt.$FSNAME-*.checksum_type:"
10271         do_nodes $(comma_list $(mdts_nodes)) \
10272                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10273
10274         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10275                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10276
10277         (( $o_count == $OSTCOUNT )) ||
10278                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10279
10280         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10281                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10282
10283         (( $m_count == $MDSCOUNT )) ||
10284                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10285 }
10286 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10287
10288 cleanup_test_78() {
10289         trap 0
10290         rm -f $DIR/$tfile
10291 }
10292
10293 test_78() { # bug 10901
10294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10295         remote_ost || skip_env "local OST"
10296
10297         NSEQ=5
10298         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10299         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10300         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10301         echo "MemTotal: $MEMTOTAL"
10302
10303         # reserve 256MB of memory for the kernel and other running processes,
10304         # and then take 1/2 of the remaining memory for the read/write buffers.
10305         if [ $MEMTOTAL -gt 512 ] ;then
10306                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10307         else
10308                 # for those poor memory-starved high-end clusters...
10309                 MEMTOTAL=$((MEMTOTAL / 2))
10310         fi
10311         echo "Mem to use for directio: $MEMTOTAL"
10312
10313         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10314         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10315         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10316         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10317                 head -n1)
10318         echo "Smallest OST: $SMALLESTOST"
10319         [[ $SMALLESTOST -lt 10240 ]] &&
10320                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10321
10322         trap cleanup_test_78 EXIT
10323
10324         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10325                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10326
10327         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10328         echo "File size: $F78SIZE"
10329         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10330         for i in $(seq 1 $NSEQ); do
10331                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10332                 echo directIO rdwr round $i of $NSEQ
10333                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10334         done
10335
10336         cleanup_test_78
10337 }
10338 run_test 78 "handle large O_DIRECT writes correctly ============"
10339
10340 test_79() { # bug 12743
10341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10342
10343         wait_delete_completed
10344
10345         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10346         BKFREE=$(calc_osc_kbytes kbytesfree)
10347         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10348
10349         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10350         DFTOTAL=`echo $STRING | cut -d, -f1`
10351         DFUSED=`echo $STRING  | cut -d, -f2`
10352         DFAVAIL=`echo $STRING | cut -d, -f3`
10353         DFFREE=$(($DFTOTAL - $DFUSED))
10354
10355         ALLOWANCE=$((64 * $OSTCOUNT))
10356
10357         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10358            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10359                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10360         fi
10361         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10362            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10363                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10364         fi
10365         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10366            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10367                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10368         fi
10369 }
10370 run_test 79 "df report consistency check ======================="
10371
10372 test_80() { # bug 10718
10373         remote_ost_nodsh && skip "remote OST with nodsh"
10374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10375
10376         # relax strong synchronous semantics for slow backends like ZFS
10377         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10378                 local soc="obdfilter.*.sync_lock_cancel"
10379                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10380
10381                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10382                 if [ -z "$save" ]; then
10383                         soc="obdfilter.*.sync_on_lock_cancel"
10384                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10385                 fi
10386
10387                 if [ "$save" != "never" ]; then
10388                         local hosts=$(comma_list $(osts_nodes))
10389
10390                         do_nodes $hosts $LCTL set_param $soc=never
10391                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10392                 fi
10393         fi
10394
10395         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10396         sync; sleep 1; sync
10397         local before=$(date +%s)
10398         cancel_lru_locks osc
10399         local after=$(date +%s)
10400         local diff=$((after - before))
10401         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10402
10403         rm -f $DIR/$tfile
10404 }
10405 run_test 80 "Page eviction is equally fast at high offsets too"
10406
10407 test_81a() { # LU-456
10408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10409         remote_ost_nodsh && skip "remote OST with nodsh"
10410
10411         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10412         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10413         do_facet ost1 lctl set_param fail_loc=0x80000228
10414
10415         # write should trigger a retry and success
10416         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10417         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10418         RC=$?
10419         if [ $RC -ne 0 ] ; then
10420                 error "write should success, but failed for $RC"
10421         fi
10422 }
10423 run_test 81a "OST should retry write when get -ENOSPC ==============="
10424
10425 test_81b() { # LU-456
10426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10427         remote_ost_nodsh && skip "remote OST with nodsh"
10428
10429         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10430         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10431         do_facet ost1 lctl set_param fail_loc=0x228
10432
10433         # write should retry several times and return -ENOSPC finally
10434         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10435         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10436         RC=$?
10437         ENOSPC=28
10438         if [ $RC -ne $ENOSPC ] ; then
10439                 error "dd should fail for -ENOSPC, but succeed."
10440         fi
10441 }
10442 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10443
10444 test_99() {
10445         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10446
10447         test_mkdir $DIR/$tdir.cvsroot
10448         chown $RUNAS_ID $DIR/$tdir.cvsroot
10449
10450         cd $TMP
10451         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10452
10453         cd /etc/init.d
10454         # some versions of cvs import exit(1) when asked to import links or
10455         # files they can't read.  ignore those files.
10456         local toignore=$(find . -type l -printf '-I %f\n' -o \
10457                          ! -perm /4 -printf '-I %f\n')
10458         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10459                 $tdir.reposname vtag rtag
10460
10461         cd $DIR
10462         test_mkdir $DIR/$tdir.reposname
10463         chown $RUNAS_ID $DIR/$tdir.reposname
10464         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10465
10466         cd $DIR/$tdir.reposname
10467         $RUNAS touch foo99
10468         $RUNAS cvs add -m 'addmsg' foo99
10469         $RUNAS cvs update
10470         $RUNAS cvs commit -m 'nomsg' foo99
10471         rm -fr $DIR/$tdir.cvsroot
10472 }
10473 run_test 99 "cvs strange file/directory operations"
10474
10475 test_100() {
10476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10477         [[ "$NETTYPE" =~ tcp ]] ||
10478                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10479         remote_ost_nodsh && skip "remote OST with nodsh"
10480         remote_mds_nodsh && skip "remote MDS with nodsh"
10481         remote_servers ||
10482                 skip "useless for local single node setup"
10483
10484         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10485                 [ "$PROT" != "tcp" ] && continue
10486                 RPORT=$(echo $REMOTE | cut -d: -f2)
10487                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10488
10489                 rc=0
10490                 LPORT=`echo $LOCAL | cut -d: -f2`
10491                 if [ $LPORT -ge 1024 ]; then
10492                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10493                         netstat -tna
10494                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10495                 fi
10496         done
10497         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10498 }
10499 run_test 100 "check local port using privileged port ==========="
10500
10501 function get_named_value()
10502 {
10503     local tag=$1
10504
10505     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10506 }
10507
10508 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10509                    awk '/^max_cached_mb/ { print $2 }')
10510
10511 cleanup_101a() {
10512         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10513         trap 0
10514 }
10515
10516 test_101a() {
10517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10518
10519         local s
10520         local discard
10521         local nreads=10000
10522         local cache_limit=32
10523
10524         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10525         trap cleanup_101a EXIT
10526         $LCTL set_param -n llite.*.read_ahead_stats=0
10527         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10528
10529         #
10530         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10531         #
10532         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10533         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10534
10535         discard=0
10536         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10537                    get_named_value 'read.but.discarded'); do
10538                         discard=$(($discard + $s))
10539         done
10540         cleanup_101a
10541
10542         $LCTL get_param osc.*-osc*.rpc_stats
10543         $LCTL get_param llite.*.read_ahead_stats
10544
10545         # Discard is generally zero, but sometimes a few random reads line up
10546         # and trigger larger readahead, which is wasted & leads to discards.
10547         if [[ $(($discard)) -gt $nreads ]]; then
10548                 error "too many ($discard) discarded pages"
10549         fi
10550         rm -f $DIR/$tfile || true
10551 }
10552 run_test 101a "check read-ahead for random reads"
10553
10554 setup_test101bc() {
10555         test_mkdir $DIR/$tdir
10556         local ssize=$1
10557         local FILE_LENGTH=$2
10558         STRIPE_OFFSET=0
10559
10560         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10561
10562         local list=$(comma_list $(osts_nodes))
10563         set_osd_param $list '' read_cache_enable 0
10564         set_osd_param $list '' writethrough_cache_enable 0
10565
10566         trap cleanup_test101bc EXIT
10567         # prepare the read-ahead file
10568         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10569
10570         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10571                                 count=$FILE_SIZE_MB 2> /dev/null
10572
10573 }
10574
10575 cleanup_test101bc() {
10576         trap 0
10577         rm -rf $DIR/$tdir
10578         rm -f $DIR/$tfile
10579
10580         local list=$(comma_list $(osts_nodes))
10581         set_osd_param $list '' read_cache_enable 1
10582         set_osd_param $list '' writethrough_cache_enable 1
10583 }
10584
10585 calc_total() {
10586         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10587 }
10588
10589 ra_check_101() {
10590         local read_size=$1
10591         local stripe_size=$2
10592         local stride_length=$((stripe_size / read_size))
10593         local stride_width=$((stride_length * OSTCOUNT))
10594         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10595                                 (stride_width - stride_length) ))
10596         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10597                   get_named_value 'read.but.discarded' | calc_total)
10598
10599         if [[ $discard -gt $discard_limit ]]; then
10600                 $LCTL get_param llite.*.read_ahead_stats
10601                 error "($discard) discarded pages with size (${read_size})"
10602         else
10603                 echo "Read-ahead success for size ${read_size}"
10604         fi
10605 }
10606
10607 test_101b() {
10608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10609         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10610
10611         local STRIPE_SIZE=1048576
10612         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10613
10614         if [ $SLOW == "yes" ]; then
10615                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10616         else
10617                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10618         fi
10619
10620         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10621
10622         # prepare the read-ahead file
10623         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10624         cancel_lru_locks osc
10625         for BIDX in 2 4 8 16 32 64 128 256
10626         do
10627                 local BSIZE=$((BIDX*4096))
10628                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10629                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10630                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10631                 $LCTL set_param -n llite.*.read_ahead_stats=0
10632                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10633                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10634                 cancel_lru_locks osc
10635                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10636         done
10637         cleanup_test101bc
10638         true
10639 }
10640 run_test 101b "check stride-io mode read-ahead ================="
10641
10642 test_101c() {
10643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10644
10645         local STRIPE_SIZE=1048576
10646         local FILE_LENGTH=$((STRIPE_SIZE*100))
10647         local nreads=10000
10648         local rsize=65536
10649         local osc_rpc_stats
10650
10651         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10652
10653         cancel_lru_locks osc
10654         $LCTL set_param osc.*.rpc_stats=0
10655         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10656         $LCTL get_param osc.*.rpc_stats
10657         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10658                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10659                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10660                 local size
10661
10662                 if [ $lines -le 20 ]; then
10663                         echo "continue debug"
10664                         continue
10665                 fi
10666                 for size in 1 2 4 8; do
10667                         local rpc=$(echo "$stats" |
10668                                     awk '($1 == "'$size':") {print $2; exit; }')
10669                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10670                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10671                 done
10672                 echo "$osc_rpc_stats check passed!"
10673         done
10674         cleanup_test101bc
10675         true
10676 }
10677 run_test 101c "check stripe_size aligned read-ahead"
10678
10679 test_101d() {
10680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10681
10682         local file=$DIR/$tfile
10683         local sz_MB=${FILESIZE_101d:-80}
10684         local ra_MB=${READAHEAD_MB:-40}
10685
10686         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10687         [ $free_MB -lt $sz_MB ] &&
10688                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10689
10690         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10691         $LFS setstripe -c -1 $file || error "setstripe failed"
10692
10693         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10694         echo Cancel LRU locks on lustre client to flush the client cache
10695         cancel_lru_locks osc
10696
10697         echo Disable read-ahead
10698         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10699         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10700         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10701         $LCTL get_param -n llite.*.max_read_ahead_mb
10702
10703         echo "Reading the test file $file with read-ahead disabled"
10704         local sz_KB=$((sz_MB * 1024 / 4))
10705         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10706         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10707         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10708                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10709
10710         echo "Cancel LRU locks on lustre client to flush the client cache"
10711         cancel_lru_locks osc
10712         echo Enable read-ahead with ${ra_MB}MB
10713         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10714
10715         echo "Reading the test file $file with read-ahead enabled"
10716         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10717                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10718
10719         echo "read-ahead disabled time read $raOFF"
10720         echo "read-ahead enabled time read $raON"
10721
10722         rm -f $file
10723         wait_delete_completed
10724
10725         # use awk for this check instead of bash because it handles decimals
10726         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10727                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10728 }
10729 run_test 101d "file read with and without read-ahead enabled"
10730
10731 test_101e() {
10732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10733
10734         local file=$DIR/$tfile
10735         local size_KB=500  #KB
10736         local count=100
10737         local bsize=1024
10738
10739         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10740         local need_KB=$((count * size_KB))
10741         [[ $free_KB -le $need_KB ]] &&
10742                 skip_env "Need free space $need_KB, have $free_KB"
10743
10744         echo "Creating $count ${size_KB}K test files"
10745         for ((i = 0; i < $count; i++)); do
10746                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10747         done
10748
10749         echo "Cancel LRU locks on lustre client to flush the client cache"
10750         cancel_lru_locks $OSC
10751
10752         echo "Reset readahead stats"
10753         $LCTL set_param -n llite.*.read_ahead_stats=0
10754
10755         for ((i = 0; i < $count; i++)); do
10756                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10757         done
10758
10759         $LCTL get_param llite.*.max_cached_mb
10760         $LCTL get_param llite.*.read_ahead_stats
10761         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10762                      get_named_value 'misses' | calc_total)
10763
10764         for ((i = 0; i < $count; i++)); do
10765                 rm -rf $file.$i 2>/dev/null
10766         done
10767
10768         #10000 means 20% reads are missing in readahead
10769         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10770 }
10771 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10772
10773 test_101f() {
10774         which iozone || skip_env "no iozone installed"
10775
10776         local old_debug=$($LCTL get_param debug)
10777         old_debug=${old_debug#*=}
10778         $LCTL set_param debug="reada mmap"
10779
10780         # create a test file
10781         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10782
10783         echo Cancel LRU locks on lustre client to flush the client cache
10784         cancel_lru_locks osc
10785
10786         echo Reset readahead stats
10787         $LCTL set_param -n llite.*.read_ahead_stats=0
10788
10789         echo mmap read the file with small block size
10790         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10791                 > /dev/null 2>&1
10792
10793         echo checking missing pages
10794         $LCTL get_param llite.*.read_ahead_stats
10795         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10796                         get_named_value 'misses' | calc_total)
10797
10798         $LCTL set_param debug="$old_debug"
10799         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10800         rm -f $DIR/$tfile
10801 }
10802 run_test 101f "check mmap read performance"
10803
10804 test_101g_brw_size_test() {
10805         local mb=$1
10806         local pages=$((mb * 1048576 / PAGE_SIZE))
10807         local file=$DIR/$tfile
10808
10809         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10810                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10811         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10812                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10813                         return 2
10814         done
10815
10816         stack_trap "rm -f $file" EXIT
10817         $LCTL set_param -n osc.*.rpc_stats=0
10818
10819         # 10 RPCs should be enough for the test
10820         local count=10
10821         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10822                 { error "dd write ${mb} MB blocks failed"; return 3; }
10823         cancel_lru_locks osc
10824         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10825                 { error "dd write ${mb} MB blocks failed"; return 4; }
10826
10827         # calculate number of full-sized read and write RPCs
10828         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10829                 sed -n '/pages per rpc/,/^$/p' |
10830                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10831                 END { print reads,writes }'))
10832         # allow one extra full-sized read RPC for async readahead
10833         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10834                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10835         [[ ${rpcs[1]} == $count ]] ||
10836                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10837 }
10838
10839 test_101g() {
10840         remote_ost_nodsh && skip "remote OST with nodsh"
10841
10842         local rpcs
10843         local osts=$(get_facets OST)
10844         local list=$(comma_list $(osts_nodes))
10845         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10846         local brw_size="obdfilter.*.brw_size"
10847
10848         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10849
10850         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10851
10852         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10853                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10854                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10855            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10856                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10857                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10858
10859                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10860                         suffix="M"
10861
10862                 if [[ $orig_mb -lt 16 ]]; then
10863                         save_lustre_params $osts "$brw_size" > $p
10864                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10865                                 error "set 16MB RPC size failed"
10866
10867                         echo "remount client to enable new RPC size"
10868                         remount_client $MOUNT || error "remount_client failed"
10869                 fi
10870
10871                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10872                 # should be able to set brw_size=12, but no rpc_stats for that
10873                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10874         fi
10875
10876         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10877
10878         if [[ $orig_mb -lt 16 ]]; then
10879                 restore_lustre_params < $p
10880                 remount_client $MOUNT || error "remount_client restore failed"
10881         fi
10882
10883         rm -f $p $DIR/$tfile
10884 }
10885 run_test 101g "Big bulk(4/16 MiB) readahead"
10886
10887 test_101h() {
10888         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10889
10890         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10891                 error "dd 70M file failed"
10892         echo Cancel LRU locks on lustre client to flush the client cache
10893         cancel_lru_locks osc
10894
10895         echo "Reset readahead stats"
10896         $LCTL set_param -n llite.*.read_ahead_stats 0
10897
10898         echo "Read 10M of data but cross 64M bundary"
10899         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10900         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10901                      get_named_value 'misses' | calc_total)
10902         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10903         rm -f $p $DIR/$tfile
10904 }
10905 run_test 101h "Readahead should cover current read window"
10906
10907 test_101i() {
10908         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10909                 error "dd 10M file failed"
10910
10911         local max_per_file_mb=$($LCTL get_param -n \
10912                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10913         cancel_lru_locks osc
10914         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10915         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10916                 error "set max_read_ahead_per_file_mb to 1 failed"
10917
10918         echo "Reset readahead stats"
10919         $LCTL set_param llite.*.read_ahead_stats=0
10920
10921         dd if=$DIR/$tfile of=/dev/null bs=2M
10922
10923         $LCTL get_param llite.*.read_ahead_stats
10924         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10925                      awk '/misses/ { print $2 }')
10926         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10927         rm -f $DIR/$tfile
10928 }
10929 run_test 101i "allow current readahead to exceed reservation"
10930
10931 test_101j() {
10932         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10933                 error "setstripe $DIR/$tfile failed"
10934         local file_size=$((1048576 * 16))
10935         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10936         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10937
10938         echo Disable read-ahead
10939         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10940
10941         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10942         for blk in $PAGE_SIZE 1048576 $file_size; do
10943                 cancel_lru_locks osc
10944                 echo "Reset readahead stats"
10945                 $LCTL set_param -n llite.*.read_ahead_stats=0
10946                 local count=$(($file_size / $blk))
10947                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10948                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10949                              get_named_value 'failed.to.fast.read' | calc_total)
10950                 $LCTL get_param -n llite.*.read_ahead_stats
10951                 [ $miss -eq $count ] || error "expected $count got $miss"
10952         done
10953
10954         rm -f $p $DIR/$tfile
10955 }
10956 run_test 101j "A complete read block should be submitted when no RA"
10957
10958 setup_test102() {
10959         test_mkdir $DIR/$tdir
10960         chown $RUNAS_ID $DIR/$tdir
10961         STRIPE_SIZE=65536
10962         STRIPE_OFFSET=1
10963         STRIPE_COUNT=$OSTCOUNT
10964         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10965
10966         trap cleanup_test102 EXIT
10967         cd $DIR
10968         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10969         cd $DIR/$tdir
10970         for num in 1 2 3 4; do
10971                 for count in $(seq 1 $STRIPE_COUNT); do
10972                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10973                                 local size=`expr $STRIPE_SIZE \* $num`
10974                                 local file=file"$num-$idx-$count"
10975                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10976                         done
10977                 done
10978         done
10979
10980         cd $DIR
10981         $1 tar cf $TMP/f102.tar $tdir --xattrs
10982 }
10983
10984 cleanup_test102() {
10985         trap 0
10986         rm -f $TMP/f102.tar
10987         rm -rf $DIR/d0.sanity/d102
10988 }
10989
10990 test_102a() {
10991         [ "$UID" != 0 ] && skip "must run as root"
10992         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10993                 skip_env "must have user_xattr"
10994
10995         [ -z "$(which setfattr 2>/dev/null)" ] &&
10996                 skip_env "could not find setfattr"
10997
10998         local testfile=$DIR/$tfile
10999
11000         touch $testfile
11001         echo "set/get xattr..."
11002         setfattr -n trusted.name1 -v value1 $testfile ||
11003                 error "setfattr -n trusted.name1=value1 $testfile failed"
11004         getfattr -n trusted.name1 $testfile 2> /dev/null |
11005           grep "trusted.name1=.value1" ||
11006                 error "$testfile missing trusted.name1=value1"
11007
11008         setfattr -n user.author1 -v author1 $testfile ||
11009                 error "setfattr -n user.author1=author1 $testfile failed"
11010         getfattr -n user.author1 $testfile 2> /dev/null |
11011           grep "user.author1=.author1" ||
11012                 error "$testfile missing trusted.author1=author1"
11013
11014         echo "listxattr..."
11015         setfattr -n trusted.name2 -v value2 $testfile ||
11016                 error "$testfile unable to set trusted.name2"
11017         setfattr -n trusted.name3 -v value3 $testfile ||
11018                 error "$testfile unable to set trusted.name3"
11019         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11020             grep "trusted.name" | wc -l) -eq 3 ] ||
11021                 error "$testfile missing 3 trusted.name xattrs"
11022
11023         setfattr -n user.author2 -v author2 $testfile ||
11024                 error "$testfile unable to set user.author2"
11025         setfattr -n user.author3 -v author3 $testfile ||
11026                 error "$testfile unable to set user.author3"
11027         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11028             grep "user.author" | wc -l) -eq 3 ] ||
11029                 error "$testfile missing 3 user.author xattrs"
11030
11031         echo "remove xattr..."
11032         setfattr -x trusted.name1 $testfile ||
11033                 error "$testfile error deleting trusted.name1"
11034         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11035                 error "$testfile did not delete trusted.name1 xattr"
11036
11037         setfattr -x user.author1 $testfile ||
11038                 error "$testfile error deleting user.author1"
11039         echo "set lustre special xattr ..."
11040         $LFS setstripe -c1 $testfile
11041         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11042                 awk -F "=" '/trusted.lov/ { print $2 }' )
11043         setfattr -n "trusted.lov" -v $lovea $testfile ||
11044                 error "$testfile doesn't ignore setting trusted.lov again"
11045         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11046                 error "$testfile allow setting invalid trusted.lov"
11047         rm -f $testfile
11048 }
11049 run_test 102a "user xattr test =================================="
11050
11051 check_102b_layout() {
11052         local layout="$*"
11053         local testfile=$DIR/$tfile
11054
11055         echo "test layout '$layout'"
11056         $LFS setstripe $layout $testfile || error "setstripe failed"
11057         $LFS getstripe -y $testfile
11058
11059         echo "get/set/list trusted.lov xattr ..." # b=10930
11060         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11061         [[ "$value" =~ "trusted.lov" ]] ||
11062                 error "can't get trusted.lov from $testfile"
11063         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11064                 error "getstripe failed"
11065
11066         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11067
11068         value=$(cut -d= -f2 <<<$value)
11069         # LU-13168: truncated xattr should fail if short lov_user_md header
11070         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11071                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11072         for len in $lens; do
11073                 echo "setfattr $len $testfile.2"
11074                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11075                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11076         done
11077         local stripe_size=$($LFS getstripe -S $testfile.2)
11078         local stripe_count=$($LFS getstripe -c $testfile.2)
11079         [[ $stripe_size -eq 65536 ]] ||
11080                 error "stripe size $stripe_size != 65536"
11081         [[ $stripe_count -eq $stripe_count_orig ]] ||
11082                 error "stripe count $stripe_count != $stripe_count_orig"
11083         rm $testfile $testfile.2
11084 }
11085
11086 test_102b() {
11087         [ -z "$(which setfattr 2>/dev/null)" ] &&
11088                 skip_env "could not find setfattr"
11089         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11090
11091         # check plain layout
11092         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11093
11094         # and also check composite layout
11095         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11096
11097 }
11098 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11099
11100 test_102c() {
11101         [ -z "$(which setfattr 2>/dev/null)" ] &&
11102                 skip_env "could not find setfattr"
11103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11104
11105         # b10930: get/set/list lustre.lov xattr
11106         echo "get/set/list lustre.lov xattr ..."
11107         test_mkdir $DIR/$tdir
11108         chown $RUNAS_ID $DIR/$tdir
11109         local testfile=$DIR/$tdir/$tfile
11110         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11111                 error "setstripe failed"
11112         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11113                 error "getstripe failed"
11114         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11115         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11116
11117         local testfile2=${testfile}2
11118         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11119                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11120
11121         $RUNAS $MCREATE $testfile2
11122         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11123         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11124         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11125         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11126         [ $stripe_count -eq $STRIPECOUNT ] ||
11127                 error "stripe count $stripe_count != $STRIPECOUNT"
11128 }
11129 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11130
11131 compare_stripe_info1() {
11132         local stripe_index_all_zero=true
11133
11134         for num in 1 2 3 4; do
11135                 for count in $(seq 1 $STRIPE_COUNT); do
11136                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11137                                 local size=$((STRIPE_SIZE * num))
11138                                 local file=file"$num-$offset-$count"
11139                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11140                                 [[ $stripe_size -ne $size ]] &&
11141                                     error "$file: size $stripe_size != $size"
11142                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11143                                 # allow fewer stripes to be created, ORI-601
11144                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11145                                     error "$file: count $stripe_count != $count"
11146                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11147                                 [[ $stripe_index -ne 0 ]] &&
11148                                         stripe_index_all_zero=false
11149                         done
11150                 done
11151         done
11152         $stripe_index_all_zero &&
11153                 error "all files are being extracted starting from OST index 0"
11154         return 0
11155 }
11156
11157 have_xattrs_include() {
11158         tar --help | grep -q xattrs-include &&
11159                 echo --xattrs-include="lustre.*"
11160 }
11161
11162 test_102d() {
11163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11164         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11165
11166         XINC=$(have_xattrs_include)
11167         setup_test102
11168         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11169         cd $DIR/$tdir/$tdir
11170         compare_stripe_info1
11171 }
11172 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11173
11174 test_102f() {
11175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11176         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11177
11178         XINC=$(have_xattrs_include)
11179         setup_test102
11180         test_mkdir $DIR/$tdir.restore
11181         cd $DIR
11182         tar cf - --xattrs $tdir | tar xf - \
11183                 -C $DIR/$tdir.restore --xattrs $XINC
11184         cd $DIR/$tdir.restore/$tdir
11185         compare_stripe_info1
11186 }
11187 run_test 102f "tar copy files, not keep osts"
11188
11189 grow_xattr() {
11190         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11191                 skip "must have user_xattr"
11192         [ -z "$(which setfattr 2>/dev/null)" ] &&
11193                 skip_env "could not find setfattr"
11194         [ -z "$(which getfattr 2>/dev/null)" ] &&
11195                 skip_env "could not find getfattr"
11196
11197         local xsize=${1:-1024}  # in bytes
11198         local file=$DIR/$tfile
11199         local value="$(generate_string $xsize)"
11200         local xbig=trusted.big
11201         local toobig=$2
11202
11203         touch $file
11204         log "save $xbig on $file"
11205         if [ -z "$toobig" ]
11206         then
11207                 setfattr -n $xbig -v $value $file ||
11208                         error "saving $xbig on $file failed"
11209         else
11210                 setfattr -n $xbig -v $value $file &&
11211                         error "saving $xbig on $file succeeded"
11212                 return 0
11213         fi
11214
11215         local orig=$(get_xattr_value $xbig $file)
11216         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11217
11218         local xsml=trusted.sml
11219         log "save $xsml on $file"
11220         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11221
11222         local new=$(get_xattr_value $xbig $file)
11223         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11224
11225         log "grow $xsml on $file"
11226         setfattr -n $xsml -v "$value" $file ||
11227                 error "growing $xsml on $file failed"
11228
11229         new=$(get_xattr_value $xbig $file)
11230         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11231         log "$xbig still valid after growing $xsml"
11232
11233         rm -f $file
11234 }
11235
11236 test_102h() { # bug 15777
11237         grow_xattr 1024
11238 }
11239 run_test 102h "grow xattr from inside inode to external block"
11240
11241 test_102ha() {
11242         large_xattr_enabled || skip_env "ea_inode feature disabled"
11243
11244         echo "setting xattr of max xattr size: $(max_xattr_size)"
11245         grow_xattr $(max_xattr_size)
11246
11247         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11248         echo "This should fail:"
11249         grow_xattr $(($(max_xattr_size) + 10)) 1
11250 }
11251 run_test 102ha "grow xattr from inside inode to external inode"
11252
11253 test_102i() { # bug 17038
11254         [ -z "$(which getfattr 2>/dev/null)" ] &&
11255                 skip "could not find getfattr"
11256
11257         touch $DIR/$tfile
11258         ln -s $DIR/$tfile $DIR/${tfile}link
11259         getfattr -n trusted.lov $DIR/$tfile ||
11260                 error "lgetxattr on $DIR/$tfile failed"
11261         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11262                 grep -i "no such attr" ||
11263                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11264         rm -f $DIR/$tfile $DIR/${tfile}link
11265 }
11266 run_test 102i "lgetxattr test on symbolic link ============"
11267
11268 test_102j() {
11269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11270         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11271
11272         XINC=$(have_xattrs_include)
11273         setup_test102 "$RUNAS"
11274         chown $RUNAS_ID $DIR/$tdir
11275         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11276         cd $DIR/$tdir/$tdir
11277         compare_stripe_info1 "$RUNAS"
11278 }
11279 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11280
11281 test_102k() {
11282         [ -z "$(which setfattr 2>/dev/null)" ] &&
11283                 skip "could not find setfattr"
11284
11285         touch $DIR/$tfile
11286         # b22187 just check that does not crash for regular file.
11287         setfattr -n trusted.lov $DIR/$tfile
11288         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11289         local test_kdir=$DIR/$tdir
11290         test_mkdir $test_kdir
11291         local default_size=$($LFS getstripe -S $test_kdir)
11292         local default_count=$($LFS getstripe -c $test_kdir)
11293         local default_offset=$($LFS getstripe -i $test_kdir)
11294         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11295                 error 'dir setstripe failed'
11296         setfattr -n trusted.lov $test_kdir
11297         local stripe_size=$($LFS getstripe -S $test_kdir)
11298         local stripe_count=$($LFS getstripe -c $test_kdir)
11299         local stripe_offset=$($LFS getstripe -i $test_kdir)
11300         [ $stripe_size -eq $default_size ] ||
11301                 error "stripe size $stripe_size != $default_size"
11302         [ $stripe_count -eq $default_count ] ||
11303                 error "stripe count $stripe_count != $default_count"
11304         [ $stripe_offset -eq $default_offset ] ||
11305                 error "stripe offset $stripe_offset != $default_offset"
11306         rm -rf $DIR/$tfile $test_kdir
11307 }
11308 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11309
11310 test_102l() {
11311         [ -z "$(which getfattr 2>/dev/null)" ] &&
11312                 skip "could not find getfattr"
11313
11314         # LU-532 trusted. xattr is invisible to non-root
11315         local testfile=$DIR/$tfile
11316
11317         touch $testfile
11318
11319         echo "listxattr as user..."
11320         chown $RUNAS_ID $testfile
11321         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11322             grep -q "trusted" &&
11323                 error "$testfile trusted xattrs are user visible"
11324
11325         return 0;
11326 }
11327 run_test 102l "listxattr size test =================================="
11328
11329 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11330         local path=$DIR/$tfile
11331         touch $path
11332
11333         listxattr_size_check $path || error "listattr_size_check $path failed"
11334 }
11335 run_test 102m "Ensure listxattr fails on small bufffer ========"
11336
11337 cleanup_test102
11338
11339 getxattr() { # getxattr path name
11340         # Return the base64 encoding of the value of xattr name on path.
11341         local path=$1
11342         local name=$2
11343
11344         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11345         # file: $path
11346         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11347         #
11348         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11349
11350         getfattr --absolute-names --encoding=base64 --name=$name $path |
11351                 awk -F= -v name=$name '$1 == name {
11352                         print substr($0, index($0, "=") + 1);
11353         }'
11354 }
11355
11356 test_102n() { # LU-4101 mdt: protect internal xattrs
11357         [ -z "$(which setfattr 2>/dev/null)" ] &&
11358                 skip "could not find setfattr"
11359         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11360         then
11361                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11362         fi
11363
11364         local file0=$DIR/$tfile.0
11365         local file1=$DIR/$tfile.1
11366         local xattr0=$TMP/$tfile.0
11367         local xattr1=$TMP/$tfile.1
11368         local namelist="lov lma lmv link fid version som hsm"
11369         local name
11370         local value
11371
11372         rm -rf $file0 $file1 $xattr0 $xattr1
11373         touch $file0 $file1
11374
11375         # Get 'before' xattrs of $file1.
11376         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11377
11378         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11379                 namelist+=" lfsck_namespace"
11380         for name in $namelist; do
11381                 # Try to copy xattr from $file0 to $file1.
11382                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11383
11384                 setfattr --name=trusted.$name --value="$value" $file1 ||
11385                         error "setxattr 'trusted.$name' failed"
11386
11387                 # Try to set a garbage xattr.
11388                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11389
11390                 if [[ x$name == "xlov" ]]; then
11391                         setfattr --name=trusted.lov --value="$value" $file1 &&
11392                         error "setxattr invalid 'trusted.lov' success"
11393                 else
11394                         setfattr --name=trusted.$name --value="$value" $file1 ||
11395                                 error "setxattr invalid 'trusted.$name' failed"
11396                 fi
11397
11398                 # Try to remove the xattr from $file1. We don't care if this
11399                 # appears to succeed or fail, we just don't want there to be
11400                 # any changes or crashes.
11401                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11402         done
11403
11404         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11405         then
11406                 name="lfsck_ns"
11407                 # Try to copy xattr from $file0 to $file1.
11408                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11409
11410                 setfattr --name=trusted.$name --value="$value" $file1 ||
11411                         error "setxattr 'trusted.$name' failed"
11412
11413                 # Try to set a garbage xattr.
11414                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11415
11416                 setfattr --name=trusted.$name --value="$value" $file1 ||
11417                         error "setxattr 'trusted.$name' failed"
11418
11419                 # Try to remove the xattr from $file1. We don't care if this
11420                 # appears to succeed or fail, we just don't want there to be
11421                 # any changes or crashes.
11422                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11423         fi
11424
11425         # Get 'after' xattrs of file1.
11426         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11427
11428         if ! diff $xattr0 $xattr1; then
11429                 error "before and after xattrs of '$file1' differ"
11430         fi
11431
11432         rm -rf $file0 $file1 $xattr0 $xattr1
11433
11434         return 0
11435 }
11436 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11437
11438 test_102p() { # LU-4703 setxattr did not check ownership
11439         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11440                 skip "MDS needs to be at least 2.5.56"
11441
11442         local testfile=$DIR/$tfile
11443
11444         touch $testfile
11445
11446         echo "setfacl as user..."
11447         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11448         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11449
11450         echo "setfattr as user..."
11451         setfacl -m "u:$RUNAS_ID:---" $testfile
11452         $RUNAS setfattr -x system.posix_acl_access $testfile
11453         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11454 }
11455 run_test 102p "check setxattr(2) correctly fails without permission"
11456
11457 test_102q() {
11458         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11459                 skip "MDS needs to be at least 2.6.92"
11460
11461         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11462 }
11463 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11464
11465 test_102r() {
11466         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11467                 skip "MDS needs to be at least 2.6.93"
11468
11469         touch $DIR/$tfile || error "touch"
11470         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11471         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11472         rm $DIR/$tfile || error "rm"
11473
11474         #normal directory
11475         mkdir -p $DIR/$tdir || error "mkdir"
11476         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11477         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11478         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11479                 error "$testfile error deleting user.author1"
11480         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11481                 grep "user.$(basename $tdir)" &&
11482                 error "$tdir did not delete user.$(basename $tdir)"
11483         rmdir $DIR/$tdir || error "rmdir"
11484
11485         #striped directory
11486         test_mkdir $DIR/$tdir
11487         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11488         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11489         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11490                 error "$testfile error deleting user.author1"
11491         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11492                 grep "user.$(basename $tdir)" &&
11493                 error "$tdir did not delete user.$(basename $tdir)"
11494         rmdir $DIR/$tdir || error "rm striped dir"
11495 }
11496 run_test 102r "set EAs with empty values"
11497
11498 test_102s() {
11499         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11500                 skip "MDS needs to be at least 2.11.52"
11501
11502         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11503
11504         save_lustre_params client "llite.*.xattr_cache" > $save
11505
11506         for cache in 0 1; do
11507                 lctl set_param llite.*.xattr_cache=$cache
11508
11509                 rm -f $DIR/$tfile
11510                 touch $DIR/$tfile || error "touch"
11511                 for prefix in lustre security system trusted user; do
11512                         # Note getxattr() may fail with 'Operation not
11513                         # supported' or 'No such attribute' depending
11514                         # on prefix and cache.
11515                         getfattr -n $prefix.n102s $DIR/$tfile &&
11516                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11517                 done
11518         done
11519
11520         restore_lustre_params < $save
11521 }
11522 run_test 102s "getting nonexistent xattrs should fail"
11523
11524 test_102t() {
11525         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11526                 skip "MDS needs to be at least 2.11.52"
11527
11528         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11529
11530         save_lustre_params client "llite.*.xattr_cache" > $save
11531
11532         for cache in 0 1; do
11533                 lctl set_param llite.*.xattr_cache=$cache
11534
11535                 for buf_size in 0 256; do
11536                         rm -f $DIR/$tfile
11537                         touch $DIR/$tfile || error "touch"
11538                         setfattr -n user.multiop $DIR/$tfile
11539                         $MULTIOP $DIR/$tfile oa$buf_size ||
11540                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11541                 done
11542         done
11543
11544         restore_lustre_params < $save
11545 }
11546 run_test 102t "zero length xattr values handled correctly"
11547
11548 run_acl_subtest()
11549 {
11550     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11551     return $?
11552 }
11553
11554 test_103a() {
11555         [ "$UID" != 0 ] && skip "must run as root"
11556         $GSS && skip_env "could not run under gss"
11557         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11558                 skip_env "must have acl enabled"
11559         [ -z "$(which setfacl 2>/dev/null)" ] &&
11560                 skip_env "could not find setfacl"
11561         remote_mds_nodsh && skip "remote MDS with nodsh"
11562
11563         gpasswd -a daemon bin                           # LU-5641
11564         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11565
11566         declare -a identity_old
11567
11568         for num in $(seq $MDSCOUNT); do
11569                 switch_identity $num true || identity_old[$num]=$?
11570         done
11571
11572         SAVE_UMASK=$(umask)
11573         umask 0022
11574         mkdir -p $DIR/$tdir
11575         cd $DIR/$tdir
11576
11577         echo "performing cp ..."
11578         run_acl_subtest cp || error "run_acl_subtest cp failed"
11579         echo "performing getfacl-noacl..."
11580         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11581         echo "performing misc..."
11582         run_acl_subtest misc || error  "misc test failed"
11583         echo "performing permissions..."
11584         run_acl_subtest permissions || error "permissions failed"
11585         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11586         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11587                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11588                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11589         then
11590                 echo "performing permissions xattr..."
11591                 run_acl_subtest permissions_xattr ||
11592                         error "permissions_xattr failed"
11593         fi
11594         echo "performing setfacl..."
11595         run_acl_subtest setfacl || error  "setfacl test failed"
11596
11597         # inheritance test got from HP
11598         echo "performing inheritance..."
11599         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11600         chmod +x make-tree || error "chmod +x failed"
11601         run_acl_subtest inheritance || error "inheritance test failed"
11602         rm -f make-tree
11603
11604         echo "LU-974 ignore umask when acl is enabled..."
11605         run_acl_subtest 974 || error "LU-974 umask test failed"
11606         if [ $MDSCOUNT -ge 2 ]; then
11607                 run_acl_subtest 974_remote ||
11608                         error "LU-974 umask test failed under remote dir"
11609         fi
11610
11611         echo "LU-2561 newly created file is same size as directory..."
11612         if [ "$mds1_FSTYPE" != "zfs" ]; then
11613                 run_acl_subtest 2561 || error "LU-2561 test failed"
11614         else
11615                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11616         fi
11617
11618         run_acl_subtest 4924 || error "LU-4924 test failed"
11619
11620         cd $SAVE_PWD
11621         umask $SAVE_UMASK
11622
11623         for num in $(seq $MDSCOUNT); do
11624                 if [ "${identity_old[$num]}" = 1 ]; then
11625                         switch_identity $num false || identity_old[$num]=$?
11626                 fi
11627         done
11628 }
11629 run_test 103a "acl test"
11630
11631 test_103b() {
11632         declare -a pids
11633         local U
11634
11635         for U in {0..511}; do
11636                 {
11637                 local O=$(printf "%04o" $U)
11638
11639                 umask $(printf "%04o" $((511 ^ $O)))
11640                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11641                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11642
11643                 (( $S == ($O & 0666) )) ||
11644                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11645
11646                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11647                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11648                 (( $S == ($O & 0666) )) ||
11649                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11650
11651                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11652                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11653                 (( $S == ($O & 0666) )) ||
11654                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11655                 rm -f $DIR/$tfile.[smp]$0
11656                 } &
11657                 local pid=$!
11658
11659                 # limit the concurrently running threads to 64. LU-11878
11660                 local idx=$((U % 64))
11661                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11662                 pids[idx]=$pid
11663         done
11664         wait
11665 }
11666 run_test 103b "umask lfs setstripe"
11667
11668 test_103c() {
11669         mkdir -p $DIR/$tdir
11670         cp -rp $DIR/$tdir $DIR/$tdir.bak
11671
11672         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11673                 error "$DIR/$tdir shouldn't contain default ACL"
11674         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11675                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11676         true
11677 }
11678 run_test 103c "'cp -rp' won't set empty acl"
11679
11680 test_103e() {
11681         local numacl
11682         local fileacl
11683         local saved_debug=$($LCTL get_param -n debug)
11684
11685         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11686                 skip "MDS needs to be at least 2.14.52"
11687
11688         large_xattr_enabled || skip_env "ea_inode feature disabled"
11689
11690         mkdir -p $DIR/$tdir
11691         # add big LOV EA to cause reply buffer overflow earlier
11692         $LFS setstripe -C 1000 $DIR/$tdir
11693         lctl set_param mdc.*-mdc*.stats=clear
11694
11695         $LCTL set_param debug=0
11696         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11697         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11698
11699         # add a large number of default ACLs (expect 8000+ for 2.13+)
11700         for U in {2..7000}; do
11701                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11702                         error "Able to add just $U default ACLs"
11703         done
11704         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11705         echo "$numacl default ACLs created"
11706
11707         stat $DIR/$tdir || error "Cannot stat directory"
11708         # check file creation
11709         touch $DIR/$tdir/$tfile ||
11710                 error "failed to create $tfile with $numacl default ACLs"
11711         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11712         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11713         echo "$fileacl ACLs were inherited"
11714         (( $fileacl == $numacl )) ||
11715                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11716         # check that new ACLs creation adds new ACLs to inherited ACLs
11717         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11718                 error "Cannot set new ACL"
11719         numacl=$((numacl + 1))
11720         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11721         (( $fileacl == $numacl )) ||
11722                 error "failed to add new ACL: $fileacl != $numacl as expected"
11723         # adds more ACLs to a file to reach their maximum at 8000+
11724         numacl=0
11725         for U in {20000..25000}; do
11726                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11727                 numacl=$((numacl + 1))
11728         done
11729         echo "Added $numacl more ACLs to the file"
11730         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11731         echo "Total $fileacl ACLs in file"
11732         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11733         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11734         rmdir $DIR/$tdir || error "Cannot remove directory"
11735 }
11736 run_test 103e "inheritance of big amount of default ACLs"
11737
11738 test_103f() {
11739         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11740                 skip "MDS needs to be at least 2.14.51"
11741
11742         large_xattr_enabled || skip_env "ea_inode feature disabled"
11743
11744         # enable changelog to consume more internal MDD buffers
11745         changelog_register
11746
11747         mkdir -p $DIR/$tdir
11748         # add big LOV EA
11749         $LFS setstripe -C 1000 $DIR/$tdir
11750         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11751         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11752         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11753         rmdir $DIR/$tdir || error "Cannot remove directory"
11754 }
11755 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11756
11757 test_104a() {
11758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11759
11760         touch $DIR/$tfile
11761         lfs df || error "lfs df failed"
11762         lfs df -ih || error "lfs df -ih failed"
11763         lfs df -h $DIR || error "lfs df -h $DIR failed"
11764         lfs df -i $DIR || error "lfs df -i $DIR failed"
11765         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11766         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11767
11768         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11769         lctl --device %$OSC deactivate
11770         lfs df || error "lfs df with deactivated OSC failed"
11771         lctl --device %$OSC activate
11772         # wait the osc back to normal
11773         wait_osc_import_ready client ost
11774
11775         lfs df || error "lfs df with reactivated OSC failed"
11776         rm -f $DIR/$tfile
11777 }
11778 run_test 104a "lfs df [-ih] [path] test ========================="
11779
11780 test_104b() {
11781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11782         [ $RUNAS_ID -eq $UID ] &&
11783                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11784
11785         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11786                         grep "Permission denied" | wc -l)))
11787         if [ $denied_cnt -ne 0 ]; then
11788                 error "lfs check servers test failed"
11789         fi
11790 }
11791 run_test 104b "$RUNAS lfs check servers test ===================="
11792
11793 #
11794 # Verify $1 is within range of $2.
11795 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11796 # $1 is <= 2% of $2. Else Fail.
11797 #
11798 value_in_range() {
11799         # Strip all units (M, G, T)
11800         actual=$(echo $1 | tr -d A-Z)
11801         expect=$(echo $2 | tr -d A-Z)
11802
11803         expect_lo=$(($expect * 98 / 100)) # 2% below
11804         expect_hi=$(($expect * 102 / 100)) # 2% above
11805
11806         # permit 2% drift above and below
11807         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11808 }
11809
11810 test_104c() {
11811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11812         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11813
11814         local ost_param="osd-zfs.$FSNAME-OST0000."
11815         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11816         local ofacets=$(get_facets OST)
11817         local mfacets=$(get_facets MDS)
11818         local saved_ost_blocks=
11819         local saved_mdt_blocks=
11820
11821         echo "Before recordsize change"
11822         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11823         df=($(df -h | grep "$MOUNT"$))
11824
11825         # For checking.
11826         echo "lfs output : ${lfs_df[*]}"
11827         echo "df  output : ${df[*]}"
11828
11829         for facet in ${ofacets//,/ }; do
11830                 if [ -z $saved_ost_blocks ]; then
11831                         saved_ost_blocks=$(do_facet $facet \
11832                                 lctl get_param -n $ost_param.blocksize)
11833                         echo "OST Blocksize: $saved_ost_blocks"
11834                 fi
11835                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11836                 do_facet $facet zfs set recordsize=32768 $ost
11837         done
11838
11839         # BS too small. Sufficient for functional testing.
11840         for facet in ${mfacets//,/ }; do
11841                 if [ -z $saved_mdt_blocks ]; then
11842                         saved_mdt_blocks=$(do_facet $facet \
11843                                 lctl get_param -n $mdt_param.blocksize)
11844                         echo "MDT Blocksize: $saved_mdt_blocks"
11845                 fi
11846                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11847                 do_facet $facet zfs set recordsize=32768 $mdt
11848         done
11849
11850         # Give new values chance to reflect change
11851         sleep 2
11852
11853         echo "After recordsize change"
11854         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11855         df_after=($(df -h | grep "$MOUNT"$))
11856
11857         # For checking.
11858         echo "lfs output : ${lfs_df_after[*]}"
11859         echo "df  output : ${df_after[*]}"
11860
11861         # Verify lfs df
11862         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11863                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11864         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11865                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11866         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11867                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11868
11869         # Verify df
11870         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11871                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11872         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11873                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11874         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11875                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11876
11877         # Restore MDT recordize back to original
11878         for facet in ${mfacets//,/ }; do
11879                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11880                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11881         done
11882
11883         # Restore OST recordize back to original
11884         for facet in ${ofacets//,/ }; do
11885                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11886                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11887         done
11888
11889         return 0
11890 }
11891 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11892
11893 test_105a() {
11894         # doesn't work on 2.4 kernels
11895         touch $DIR/$tfile
11896         if $(flock_is_enabled); then
11897                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11898         else
11899                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11900         fi
11901         rm -f $DIR/$tfile
11902 }
11903 run_test 105a "flock when mounted without -o flock test ========"
11904
11905 test_105b() {
11906         touch $DIR/$tfile
11907         if $(flock_is_enabled); then
11908                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11909         else
11910                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11911         fi
11912         rm -f $DIR/$tfile
11913 }
11914 run_test 105b "fcntl when mounted without -o flock test ========"
11915
11916 test_105c() {
11917         touch $DIR/$tfile
11918         if $(flock_is_enabled); then
11919                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11920         else
11921                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11922         fi
11923         rm -f $DIR/$tfile
11924 }
11925 run_test 105c "lockf when mounted without -o flock test"
11926
11927 test_105d() { # bug 15924
11928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11929
11930         test_mkdir $DIR/$tdir
11931         flock_is_enabled || skip_env "mount w/o flock enabled"
11932         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11933         $LCTL set_param fail_loc=0x80000315
11934         flocks_test 2 $DIR/$tdir
11935 }
11936 run_test 105d "flock race (should not freeze) ========"
11937
11938 test_105e() { # bug 22660 && 22040
11939         flock_is_enabled || skip_env "mount w/o flock enabled"
11940
11941         touch $DIR/$tfile
11942         flocks_test 3 $DIR/$tfile
11943 }
11944 run_test 105e "Two conflicting flocks from same process"
11945
11946 test_106() { #bug 10921
11947         test_mkdir $DIR/$tdir
11948         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11949         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11950 }
11951 run_test 106 "attempt exec of dir followed by chown of that dir"
11952
11953 test_107() {
11954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11955
11956         CDIR=`pwd`
11957         local file=core
11958
11959         cd $DIR
11960         rm -f $file
11961
11962         local save_pattern=$(sysctl -n kernel.core_pattern)
11963         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11964         sysctl -w kernel.core_pattern=$file
11965         sysctl -w kernel.core_uses_pid=0
11966
11967         ulimit -c unlimited
11968         sleep 60 &
11969         SLEEPPID=$!
11970
11971         sleep 1
11972
11973         kill -s 11 $SLEEPPID
11974         wait $SLEEPPID
11975         if [ -e $file ]; then
11976                 size=`stat -c%s $file`
11977                 [ $size -eq 0 ] && error "Fail to create core file $file"
11978         else
11979                 error "Fail to create core file $file"
11980         fi
11981         rm -f $file
11982         sysctl -w kernel.core_pattern=$save_pattern
11983         sysctl -w kernel.core_uses_pid=$save_uses_pid
11984         cd $CDIR
11985 }
11986 run_test 107 "Coredump on SIG"
11987
11988 test_110() {
11989         test_mkdir $DIR/$tdir
11990         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11991         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11992                 error "mkdir with 256 char should fail, but did not"
11993         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11994                 error "create with 255 char failed"
11995         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11996                 error "create with 256 char should fail, but did not"
11997
11998         ls -l $DIR/$tdir
11999         rm -rf $DIR/$tdir
12000 }
12001 run_test 110 "filename length checking"
12002
12003 #
12004 # Purpose: To verify dynamic thread (OSS) creation.
12005 #
12006 test_115() {
12007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12008         remote_ost_nodsh && skip "remote OST with nodsh"
12009
12010         # Lustre does not stop service threads once they are started.
12011         # Reset number of running threads to default.
12012         stopall
12013         setupall
12014
12015         local OSTIO_pre
12016         local save_params="$TMP/sanity-$TESTNAME.parameters"
12017
12018         # Get ll_ost_io count before I/O
12019         OSTIO_pre=$(do_facet ost1 \
12020                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
12021         # Exit if lustre is not running (ll_ost_io not running).
12022         [ -z "$OSTIO_pre" ] && error "no OSS threads"
12023
12024         echo "Starting with $OSTIO_pre threads"
12025         local thread_max=$((OSTIO_pre * 2))
12026         local rpc_in_flight=$((thread_max * 2))
12027         # this is limited to OSC_MAX_RIF_MAX (256)
12028         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12029         thread_max=$((rpc_in_flight / 2))
12030         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12031                 return
12032
12033         # Number of I/O Process proposed to be started.
12034         local nfiles
12035         local facets=$(get_facets OST)
12036
12037         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12038         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12039
12040         # Set in_flight to $rpc_in_flight
12041         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12042                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12043         nfiles=${rpc_in_flight}
12044         # Set ost thread_max to $thread_max
12045         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12046
12047         # 5 Minutes should be sufficient for max number of OSS
12048         # threads(thread_max) to be created.
12049         local timeout=300
12050
12051         # Start I/O.
12052         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12053         test_mkdir $DIR/$tdir
12054         for i in $(seq $nfiles); do
12055                 local file=$DIR/$tdir/${tfile}-$i
12056                 $LFS setstripe -c -1 -i 0 $file
12057                 ($WTL $file $timeout)&
12058         done
12059
12060         # I/O Started - Wait for thread_started to reach thread_max or report
12061         # error if thread_started is more than thread_max.
12062         echo "Waiting for thread_started to reach thread_max"
12063         local thread_started=0
12064         local end_time=$((SECONDS + timeout))
12065
12066         while [ $SECONDS -le $end_time ] ; do
12067                 echo -n "."
12068                 # Get ost i/o thread_started count.
12069                 thread_started=$(do_facet ost1 \
12070                         "$LCTL get_param \
12071                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12072                 # Break out if thread_started is equal/greater than thread_max
12073                 if [[ $thread_started -ge $thread_max ]]; then
12074                         echo ll_ost_io thread_started $thread_started, \
12075                                 equal/greater than thread_max $thread_max
12076                         break
12077                 fi
12078                 sleep 1
12079         done
12080
12081         # Cleanup - We have the numbers, Kill i/o jobs if running.
12082         jobcount=($(jobs -p))
12083         for i in $(seq 0 $((${#jobcount[@]}-1)))
12084         do
12085                 kill -9 ${jobcount[$i]}
12086                 if [ $? -ne 0 ] ; then
12087                         echo Warning: \
12088                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12089                 fi
12090         done
12091
12092         # Cleanup files left by WTL binary.
12093         for i in $(seq $nfiles); do
12094                 local file=$DIR/$tdir/${tfile}-$i
12095                 rm -rf $file
12096                 if [ $? -ne 0 ] ; then
12097                         echo "Warning: Failed to delete file $file"
12098                 fi
12099         done
12100
12101         restore_lustre_params <$save_params
12102         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12103
12104         # Error out if no new thread has started or Thread started is greater
12105         # than thread max.
12106         if [[ $thread_started -le $OSTIO_pre ||
12107                         $thread_started -gt $thread_max ]]; then
12108                 error "ll_ost_io: thread_started $thread_started" \
12109                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12110                       "No new thread started or thread started greater " \
12111                       "than thread_max."
12112         fi
12113 }
12114 run_test 115 "verify dynamic thread creation===================="
12115
12116 test_116a() { # was previously test_116()
12117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12118         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12119         remote_mds_nodsh && skip "remote MDS with nodsh"
12120
12121         echo -n "Free space priority "
12122         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12123                 head -n1
12124         declare -a AVAIL
12125         free_min_max
12126
12127         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12128         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12129         stack_trap simple_cleanup_common
12130
12131         # Check if we need to generate uneven OSTs
12132         test_mkdir -p $DIR/$tdir/OST${MINI}
12133         local FILL=$((MINV / 4))
12134         local DIFF=$((MAXV - MINV))
12135         local DIFF2=$((DIFF * 100 / MINV))
12136
12137         local threshold=$(do_facet $SINGLEMDS \
12138                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12139         threshold=${threshold%%%}
12140         echo -n "Check for uneven OSTs: "
12141         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12142
12143         if [[ $DIFF2 -gt $threshold ]]; then
12144                 echo "ok"
12145                 echo "Don't need to fill OST$MINI"
12146         else
12147                 # generate uneven OSTs. Write 2% over the QOS threshold value
12148                 echo "no"
12149                 DIFF=$((threshold - DIFF2 + 2))
12150                 DIFF2=$((MINV * DIFF / 100))
12151                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12152                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12153                         error "setstripe failed"
12154                 DIFF=$((DIFF2 / 2048))
12155                 i=0
12156                 while [ $i -lt $DIFF ]; do
12157                         i=$((i + 1))
12158                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12159                                 bs=2M count=1 2>/dev/null
12160                         echo -n .
12161                 done
12162                 echo .
12163                 sync
12164                 sleep_maxage
12165                 free_min_max
12166         fi
12167
12168         DIFF=$((MAXV - MINV))
12169         DIFF2=$((DIFF * 100 / MINV))
12170         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12171         if [ $DIFF2 -gt $threshold ]; then
12172                 echo "ok"
12173         else
12174                 skip "QOS imbalance criteria not met"
12175         fi
12176
12177         MINI1=$MINI
12178         MINV1=$MINV
12179         MAXI1=$MAXI
12180         MAXV1=$MAXV
12181
12182         # now fill using QOS
12183         $LFS setstripe -c 1 $DIR/$tdir
12184         FILL=$((FILL / 200))
12185         if [ $FILL -gt 600 ]; then
12186                 FILL=600
12187         fi
12188         echo "writing $FILL files to QOS-assigned OSTs"
12189         i=0
12190         while [ $i -lt $FILL ]; do
12191                 i=$((i + 1))
12192                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12193                         count=1 2>/dev/null
12194                 echo -n .
12195         done
12196         echo "wrote $i 200k files"
12197         sync
12198         sleep_maxage
12199
12200         echo "Note: free space may not be updated, so measurements might be off"
12201         free_min_max
12202         DIFF2=$((MAXV - MINV))
12203         echo "free space delta: orig $DIFF final $DIFF2"
12204         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12205         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12206         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12207         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12208         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12209         if [[ $DIFF -gt 0 ]]; then
12210                 FILL=$((DIFF2 * 100 / DIFF - 100))
12211                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12212         fi
12213
12214         # Figure out which files were written where
12215         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12216                awk '/'$MINI1': / {print $2; exit}')
12217         echo $UUID
12218         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12219         echo "$MINC files created on smaller OST $MINI1"
12220         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12221                awk '/'$MAXI1': / {print $2; exit}')
12222         echo $UUID
12223         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12224         echo "$MAXC files created on larger OST $MAXI1"
12225         if [[ $MINC -gt 0 ]]; then
12226                 FILL=$((MAXC * 100 / MINC - 100))
12227                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12228         fi
12229         [[ $MAXC -gt $MINC ]] ||
12230                 error_ignore LU-9 "stripe QOS didn't balance free space"
12231 }
12232 run_test 116a "stripe QOS: free space balance ==================="
12233
12234 test_116b() { # LU-2093
12235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12236         remote_mds_nodsh && skip "remote MDS with nodsh"
12237
12238 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12239         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12240                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12241         [ -z "$old_rr" ] && skip "no QOS"
12242         do_facet $SINGLEMDS lctl set_param \
12243                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12244         mkdir -p $DIR/$tdir
12245         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12246         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12247         do_facet $SINGLEMDS lctl set_param fail_loc=0
12248         rm -rf $DIR/$tdir
12249         do_facet $SINGLEMDS lctl set_param \
12250                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12251 }
12252 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12253
12254 test_117() # bug 10891
12255 {
12256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12257
12258         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12259         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12260         lctl set_param fail_loc=0x21e
12261         > $DIR/$tfile || error "truncate failed"
12262         lctl set_param fail_loc=0
12263         echo "Truncate succeeded."
12264         rm -f $DIR/$tfile
12265 }
12266 run_test 117 "verify osd extend =========="
12267
12268 NO_SLOW_RESENDCOUNT=4
12269 export OLD_RESENDCOUNT=""
12270 set_resend_count () {
12271         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12272         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12273         lctl set_param -n $PROC_RESENDCOUNT $1
12274         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12275 }
12276
12277 # for reduce test_118* time (b=14842)
12278 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12279
12280 # Reset async IO behavior after error case
12281 reset_async() {
12282         FILE=$DIR/reset_async
12283
12284         # Ensure all OSCs are cleared
12285         $LFS setstripe -c -1 $FILE
12286         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12287         sync
12288         rm $FILE
12289 }
12290
12291 test_118a() #bug 11710
12292 {
12293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12294
12295         reset_async
12296
12297         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12298         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12299         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12300
12301         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12302                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12303                 return 1;
12304         fi
12305         rm -f $DIR/$tfile
12306 }
12307 run_test 118a "verify O_SYNC works =========="
12308
12309 test_118b()
12310 {
12311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12312         remote_ost_nodsh && skip "remote OST with nodsh"
12313
12314         reset_async
12315
12316         #define OBD_FAIL_SRV_ENOENT 0x217
12317         set_nodes_failloc "$(osts_nodes)" 0x217
12318         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12319         RC=$?
12320         set_nodes_failloc "$(osts_nodes)" 0
12321         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12322         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12323                     grep -c writeback)
12324
12325         if [[ $RC -eq 0 ]]; then
12326                 error "Must return error due to dropped pages, rc=$RC"
12327                 return 1;
12328         fi
12329
12330         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12331                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12332                 return 1;
12333         fi
12334
12335         echo "Dirty pages not leaked on ENOENT"
12336
12337         # Due to the above error the OSC will issue all RPCs syncronously
12338         # until a subsequent RPC completes successfully without error.
12339         $MULTIOP $DIR/$tfile Ow4096yc
12340         rm -f $DIR/$tfile
12341
12342         return 0
12343 }
12344 run_test 118b "Reclaim dirty pages on fatal error =========="
12345
12346 test_118c()
12347 {
12348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12349
12350         # for 118c, restore the original resend count, LU-1940
12351         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12352                                 set_resend_count $OLD_RESENDCOUNT
12353         remote_ost_nodsh && skip "remote OST with nodsh"
12354
12355         reset_async
12356
12357         #define OBD_FAIL_OST_EROFS               0x216
12358         set_nodes_failloc "$(osts_nodes)" 0x216
12359
12360         # multiop should block due to fsync until pages are written
12361         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12362         MULTIPID=$!
12363         sleep 1
12364
12365         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12366                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12367         fi
12368
12369         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12370                     grep -c writeback)
12371         if [[ $WRITEBACK -eq 0 ]]; then
12372                 error "No page in writeback, writeback=$WRITEBACK"
12373         fi
12374
12375         set_nodes_failloc "$(osts_nodes)" 0
12376         wait $MULTIPID
12377         RC=$?
12378         if [[ $RC -ne 0 ]]; then
12379                 error "Multiop fsync failed, rc=$RC"
12380         fi
12381
12382         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12383         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12384                     grep -c writeback)
12385         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12386                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12387         fi
12388
12389         rm -f $DIR/$tfile
12390         echo "Dirty pages flushed via fsync on EROFS"
12391         return 0
12392 }
12393 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12394
12395 # continue to use small resend count to reduce test_118* time (b=14842)
12396 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12397
12398 test_118d()
12399 {
12400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12401         remote_ost_nodsh && skip "remote OST with nodsh"
12402
12403         reset_async
12404
12405         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12406         set_nodes_failloc "$(osts_nodes)" 0x214
12407         # multiop should block due to fsync until pages are written
12408         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12409         MULTIPID=$!
12410         sleep 1
12411
12412         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12413                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12414         fi
12415
12416         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12417                     grep -c writeback)
12418         if [[ $WRITEBACK -eq 0 ]]; then
12419                 error "No page in writeback, writeback=$WRITEBACK"
12420         fi
12421
12422         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12423         set_nodes_failloc "$(osts_nodes)" 0
12424
12425         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12426         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12427                     grep -c writeback)
12428         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12429                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12430         fi
12431
12432         rm -f $DIR/$tfile
12433         echo "Dirty pages gaurenteed flushed via fsync"
12434         return 0
12435 }
12436 run_test 118d "Fsync validation inject a delay of the bulk =========="
12437
12438 test_118f() {
12439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12440
12441         reset_async
12442
12443         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12444         lctl set_param fail_loc=0x8000040a
12445
12446         # Should simulate EINVAL error which is fatal
12447         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12448         RC=$?
12449         if [[ $RC -eq 0 ]]; then
12450                 error "Must return error due to dropped pages, rc=$RC"
12451         fi
12452
12453         lctl set_param fail_loc=0x0
12454
12455         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12456         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12457         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12458                     grep -c writeback)
12459         if [[ $LOCKED -ne 0 ]]; then
12460                 error "Locked pages remain in cache, locked=$LOCKED"
12461         fi
12462
12463         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12464                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12465         fi
12466
12467         rm -f $DIR/$tfile
12468         echo "No pages locked after fsync"
12469
12470         reset_async
12471         return 0
12472 }
12473 run_test 118f "Simulate unrecoverable OSC side error =========="
12474
12475 test_118g() {
12476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12477
12478         reset_async
12479
12480         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12481         lctl set_param fail_loc=0x406
12482
12483         # simulate local -ENOMEM
12484         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12485         RC=$?
12486
12487         lctl set_param fail_loc=0
12488         if [[ $RC -eq 0 ]]; then
12489                 error "Must return error due to dropped pages, rc=$RC"
12490         fi
12491
12492         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12493         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12494         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12495                         grep -c writeback)
12496         if [[ $LOCKED -ne 0 ]]; then
12497                 error "Locked pages remain in cache, locked=$LOCKED"
12498         fi
12499
12500         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12501                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12502         fi
12503
12504         rm -f $DIR/$tfile
12505         echo "No pages locked after fsync"
12506
12507         reset_async
12508         return 0
12509 }
12510 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12511
12512 test_118h() {
12513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12514         remote_ost_nodsh && skip "remote OST with nodsh"
12515
12516         reset_async
12517
12518         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12519         set_nodes_failloc "$(osts_nodes)" 0x20e
12520         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12521         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12522         RC=$?
12523
12524         set_nodes_failloc "$(osts_nodes)" 0
12525         if [[ $RC -eq 0 ]]; then
12526                 error "Must return error due to dropped pages, rc=$RC"
12527         fi
12528
12529         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12530         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12531         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12532                     grep -c writeback)
12533         if [[ $LOCKED -ne 0 ]]; then
12534                 error "Locked pages remain in cache, locked=$LOCKED"
12535         fi
12536
12537         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12538                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12539         fi
12540
12541         rm -f $DIR/$tfile
12542         echo "No pages locked after fsync"
12543
12544         return 0
12545 }
12546 run_test 118h "Verify timeout in handling recoverables errors  =========="
12547
12548 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12549
12550 test_118i() {
12551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12552         remote_ost_nodsh && skip "remote OST with nodsh"
12553
12554         reset_async
12555
12556         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12557         set_nodes_failloc "$(osts_nodes)" 0x20e
12558
12559         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12560         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12561         PID=$!
12562         sleep 5
12563         set_nodes_failloc "$(osts_nodes)" 0
12564
12565         wait $PID
12566         RC=$?
12567         if [[ $RC -ne 0 ]]; then
12568                 error "got error, but should be not, rc=$RC"
12569         fi
12570
12571         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12572         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12573         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12574         if [[ $LOCKED -ne 0 ]]; then
12575                 error "Locked pages remain in cache, locked=$LOCKED"
12576         fi
12577
12578         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12579                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12580         fi
12581
12582         rm -f $DIR/$tfile
12583         echo "No pages locked after fsync"
12584
12585         return 0
12586 }
12587 run_test 118i "Fix error before timeout in recoverable error  =========="
12588
12589 [ "$SLOW" = "no" ] && set_resend_count 4
12590
12591 test_118j() {
12592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12593         remote_ost_nodsh && skip "remote OST with nodsh"
12594
12595         reset_async
12596
12597         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12598         set_nodes_failloc "$(osts_nodes)" 0x220
12599
12600         # return -EIO from OST
12601         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12602         RC=$?
12603         set_nodes_failloc "$(osts_nodes)" 0x0
12604         if [[ $RC -eq 0 ]]; then
12605                 error "Must return error due to dropped pages, rc=$RC"
12606         fi
12607
12608         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12609         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12610         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12611         if [[ $LOCKED -ne 0 ]]; then
12612                 error "Locked pages remain in cache, locked=$LOCKED"
12613         fi
12614
12615         # in recoverable error on OST we want resend and stay until it finished
12616         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12617                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12618         fi
12619
12620         rm -f $DIR/$tfile
12621         echo "No pages locked after fsync"
12622
12623         return 0
12624 }
12625 run_test 118j "Simulate unrecoverable OST side error =========="
12626
12627 test_118k()
12628 {
12629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12630         remote_ost_nodsh && skip "remote OSTs with nodsh"
12631
12632         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12633         set_nodes_failloc "$(osts_nodes)" 0x20e
12634         test_mkdir $DIR/$tdir
12635
12636         for ((i=0;i<10;i++)); do
12637                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12638                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12639                 SLEEPPID=$!
12640                 sleep 0.500s
12641                 kill $SLEEPPID
12642                 wait $SLEEPPID
12643         done
12644
12645         set_nodes_failloc "$(osts_nodes)" 0
12646         rm -rf $DIR/$tdir
12647 }
12648 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12649
12650 test_118l() # LU-646
12651 {
12652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12653
12654         test_mkdir $DIR/$tdir
12655         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12656         rm -rf $DIR/$tdir
12657 }
12658 run_test 118l "fsync dir"
12659
12660 test_118m() # LU-3066
12661 {
12662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12663
12664         test_mkdir $DIR/$tdir
12665         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12666         rm -rf $DIR/$tdir
12667 }
12668 run_test 118m "fdatasync dir ========="
12669
12670 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12671
12672 test_118n()
12673 {
12674         local begin
12675         local end
12676
12677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12678         remote_ost_nodsh && skip "remote OSTs with nodsh"
12679
12680         # Sleep to avoid a cached response.
12681         #define OBD_STATFS_CACHE_SECONDS 1
12682         sleep 2
12683
12684         # Inject a 10 second delay in the OST_STATFS handler.
12685         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12686         set_nodes_failloc "$(osts_nodes)" 0x242
12687
12688         begin=$SECONDS
12689         stat --file-system $MOUNT > /dev/null
12690         end=$SECONDS
12691
12692         set_nodes_failloc "$(osts_nodes)" 0
12693
12694         if ((end - begin > 20)); then
12695             error "statfs took $((end - begin)) seconds, expected 10"
12696         fi
12697 }
12698 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12699
12700 test_119a() # bug 11737
12701 {
12702         BSIZE=$((512 * 1024))
12703         directio write $DIR/$tfile 0 1 $BSIZE
12704         # We ask to read two blocks, which is more than a file size.
12705         # directio will indicate an error when requested and actual
12706         # sizes aren't equeal (a normal situation in this case) and
12707         # print actual read amount.
12708         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12709         if [ "$NOB" != "$BSIZE" ]; then
12710                 error "read $NOB bytes instead of $BSIZE"
12711         fi
12712         rm -f $DIR/$tfile
12713 }
12714 run_test 119a "Short directIO read must return actual read amount"
12715
12716 test_119b() # bug 11737
12717 {
12718         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12719
12720         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12721         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12722         sync
12723         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12724                 error "direct read failed"
12725         rm -f $DIR/$tfile
12726 }
12727 run_test 119b "Sparse directIO read must return actual read amount"
12728
12729 test_119c() # bug 13099
12730 {
12731         BSIZE=1048576
12732         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12733         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12734         rm -f $DIR/$tfile
12735 }
12736 run_test 119c "Testing for direct read hitting hole"
12737
12738 test_119d() # bug 15950
12739 {
12740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12741
12742         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12743         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12744         BSIZE=1048576
12745         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12746         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12747         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12748         lctl set_param fail_loc=0x40d
12749         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12750         pid_dio=$!
12751         sleep 1
12752         cat $DIR/$tfile > /dev/null &
12753         lctl set_param fail_loc=0
12754         pid_reads=$!
12755         wait $pid_dio
12756         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12757         sleep 2
12758         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12759         error "the read rpcs have not completed in 2s"
12760         rm -f $DIR/$tfile
12761         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12762 }
12763 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12764
12765 test_120a() {
12766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12767         remote_mds_nodsh && skip "remote MDS with nodsh"
12768         test_mkdir -i0 -c1 $DIR/$tdir
12769         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12770                 skip_env "no early lock cancel on server"
12771
12772         lru_resize_disable mdc
12773         lru_resize_disable osc
12774         cancel_lru_locks mdc
12775         # asynchronous object destroy at MDT could cause bl ast to client
12776         cancel_lru_locks osc
12777
12778         stat $DIR/$tdir > /dev/null
12779         can1=$(do_facet mds1 \
12780                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12781                awk '/ldlm_cancel/ {print $2}')
12782         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12783                awk '/ldlm_bl_callback/ {print $2}')
12784         test_mkdir -i0 -c1 $DIR/$tdir/d1
12785         can2=$(do_facet mds1 \
12786                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12787                awk '/ldlm_cancel/ {print $2}')
12788         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12789                awk '/ldlm_bl_callback/ {print $2}')
12790         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12791         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12792         lru_resize_enable mdc
12793         lru_resize_enable osc
12794 }
12795 run_test 120a "Early Lock Cancel: mkdir test"
12796
12797 test_120b() {
12798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12799         remote_mds_nodsh && skip "remote MDS with nodsh"
12800         test_mkdir $DIR/$tdir
12801         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12802                 skip_env "no early lock cancel on server"
12803
12804         lru_resize_disable mdc
12805         lru_resize_disable osc
12806         cancel_lru_locks mdc
12807         stat $DIR/$tdir > /dev/null
12808         can1=$(do_facet $SINGLEMDS \
12809                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12810                awk '/ldlm_cancel/ {print $2}')
12811         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12812                awk '/ldlm_bl_callback/ {print $2}')
12813         touch $DIR/$tdir/f1
12814         can2=$(do_facet $SINGLEMDS \
12815                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12816                awk '/ldlm_cancel/ {print $2}')
12817         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12818                awk '/ldlm_bl_callback/ {print $2}')
12819         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12820         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12821         lru_resize_enable mdc
12822         lru_resize_enable osc
12823 }
12824 run_test 120b "Early Lock Cancel: create test"
12825
12826 test_120c() {
12827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12828         remote_mds_nodsh && skip "remote MDS with nodsh"
12829         test_mkdir -i0 -c1 $DIR/$tdir
12830         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12831                 skip "no early lock cancel on server"
12832
12833         lru_resize_disable mdc
12834         lru_resize_disable osc
12835         test_mkdir -i0 -c1 $DIR/$tdir/d1
12836         test_mkdir -i0 -c1 $DIR/$tdir/d2
12837         touch $DIR/$tdir/d1/f1
12838         cancel_lru_locks mdc
12839         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12840         can1=$(do_facet mds1 \
12841                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12842                awk '/ldlm_cancel/ {print $2}')
12843         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12844                awk '/ldlm_bl_callback/ {print $2}')
12845         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12846         can2=$(do_facet mds1 \
12847                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12848                awk '/ldlm_cancel/ {print $2}')
12849         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12850                awk '/ldlm_bl_callback/ {print $2}')
12851         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12852         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12853         lru_resize_enable mdc
12854         lru_resize_enable osc
12855 }
12856 run_test 120c "Early Lock Cancel: link test"
12857
12858 test_120d() {
12859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12860         remote_mds_nodsh && skip "remote MDS with nodsh"
12861         test_mkdir -i0 -c1 $DIR/$tdir
12862         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12863                 skip_env "no early lock cancel on server"
12864
12865         lru_resize_disable mdc
12866         lru_resize_disable osc
12867         touch $DIR/$tdir
12868         cancel_lru_locks mdc
12869         stat $DIR/$tdir > /dev/null
12870         can1=$(do_facet mds1 \
12871                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12872                awk '/ldlm_cancel/ {print $2}')
12873         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12874                awk '/ldlm_bl_callback/ {print $2}')
12875         chmod a+x $DIR/$tdir
12876         can2=$(do_facet mds1 \
12877                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12878                awk '/ldlm_cancel/ {print $2}')
12879         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12880                awk '/ldlm_bl_callback/ {print $2}')
12881         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12882         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12883         lru_resize_enable mdc
12884         lru_resize_enable osc
12885 }
12886 run_test 120d "Early Lock Cancel: setattr test"
12887
12888 test_120e() {
12889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12890         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12891                 skip_env "no early lock cancel on server"
12892         remote_mds_nodsh && skip "remote MDS with nodsh"
12893
12894         local dlmtrace_set=false
12895
12896         test_mkdir -i0 -c1 $DIR/$tdir
12897         lru_resize_disable mdc
12898         lru_resize_disable osc
12899         ! $LCTL get_param debug | grep -q dlmtrace &&
12900                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12901         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12902         cancel_lru_locks mdc
12903         cancel_lru_locks osc
12904         dd if=$DIR/$tdir/f1 of=/dev/null
12905         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12906         # XXX client can not do early lock cancel of OST lock
12907         # during unlink (LU-4206), so cancel osc lock now.
12908         sleep 2
12909         cancel_lru_locks osc
12910         can1=$(do_facet mds1 \
12911                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12912                awk '/ldlm_cancel/ {print $2}')
12913         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12914                awk '/ldlm_bl_callback/ {print $2}')
12915         unlink $DIR/$tdir/f1
12916         sleep 5
12917         can2=$(do_facet mds1 \
12918                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12919                awk '/ldlm_cancel/ {print $2}')
12920         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12921                awk '/ldlm_bl_callback/ {print $2}')
12922         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12923                 $LCTL dk $TMP/cancel.debug.txt
12924         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12925                 $LCTL dk $TMP/blocking.debug.txt
12926         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12927         lru_resize_enable mdc
12928         lru_resize_enable osc
12929 }
12930 run_test 120e "Early Lock Cancel: unlink test"
12931
12932 test_120f() {
12933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12934         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12935                 skip_env "no early lock cancel on server"
12936         remote_mds_nodsh && skip "remote MDS with nodsh"
12937
12938         test_mkdir -i0 -c1 $DIR/$tdir
12939         lru_resize_disable mdc
12940         lru_resize_disable osc
12941         test_mkdir -i0 -c1 $DIR/$tdir/d1
12942         test_mkdir -i0 -c1 $DIR/$tdir/d2
12943         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12944         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12945         cancel_lru_locks mdc
12946         cancel_lru_locks osc
12947         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12948         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12949         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12950         # XXX client can not do early lock cancel of OST lock
12951         # during rename (LU-4206), so cancel osc lock now.
12952         sleep 2
12953         cancel_lru_locks osc
12954         can1=$(do_facet mds1 \
12955                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12956                awk '/ldlm_cancel/ {print $2}')
12957         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12958                awk '/ldlm_bl_callback/ {print $2}')
12959         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12960         sleep 5
12961         can2=$(do_facet mds1 \
12962                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12963                awk '/ldlm_cancel/ {print $2}')
12964         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12965                awk '/ldlm_bl_callback/ {print $2}')
12966         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12967         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12968         lru_resize_enable mdc
12969         lru_resize_enable osc
12970 }
12971 run_test 120f "Early Lock Cancel: rename test"
12972
12973 test_120g() {
12974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12975         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12976                 skip_env "no early lock cancel on server"
12977         remote_mds_nodsh && skip "remote MDS with nodsh"
12978
12979         lru_resize_disable mdc
12980         lru_resize_disable osc
12981         count=10000
12982         echo create $count files
12983         test_mkdir $DIR/$tdir
12984         cancel_lru_locks mdc
12985         cancel_lru_locks osc
12986         t0=$(date +%s)
12987
12988         can0=$(do_facet $SINGLEMDS \
12989                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12990                awk '/ldlm_cancel/ {print $2}')
12991         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12992                awk '/ldlm_bl_callback/ {print $2}')
12993         createmany -o $DIR/$tdir/f $count
12994         sync
12995         can1=$(do_facet $SINGLEMDS \
12996                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12997                awk '/ldlm_cancel/ {print $2}')
12998         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12999                awk '/ldlm_bl_callback/ {print $2}')
13000         t1=$(date +%s)
13001         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13002         echo rm $count files
13003         rm -r $DIR/$tdir
13004         sync
13005         can2=$(do_facet $SINGLEMDS \
13006                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13007                awk '/ldlm_cancel/ {print $2}')
13008         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13009                awk '/ldlm_bl_callback/ {print $2}')
13010         t2=$(date +%s)
13011         echo total: $count removes in $((t2-t1))
13012         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13013         sleep 2
13014         # wait for commitment of removal
13015         lru_resize_enable mdc
13016         lru_resize_enable osc
13017 }
13018 run_test 120g "Early Lock Cancel: performance test"
13019
13020 test_121() { #bug #10589
13021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13022
13023         rm -rf $DIR/$tfile
13024         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13025 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13026         lctl set_param fail_loc=0x310
13027         cancel_lru_locks osc > /dev/null
13028         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13029         lctl set_param fail_loc=0
13030         [[ $reads -eq $writes ]] ||
13031                 error "read $reads blocks, must be $writes blocks"
13032 }
13033 run_test 121 "read cancel race ========="
13034
13035 test_123a_base() { # was test 123, statahead(bug 11401)
13036         local lsx="$1"
13037
13038         SLOWOK=0
13039         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13040                 log "testing UP system. Performance may be lower than expected."
13041                 SLOWOK=1
13042         fi
13043         running_in_vm && SLOWOK=1
13044
13045         rm -rf $DIR/$tdir
13046         test_mkdir $DIR/$tdir
13047         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13048         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13049         MULT=10
13050         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13051                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13052
13053                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13054                 lctl set_param -n llite.*.statahead_max 0
13055                 lctl get_param llite.*.statahead_max
13056                 cancel_lru_locks mdc
13057                 cancel_lru_locks osc
13058                 stime=$(date +%s)
13059                 time $lsx $DIR/$tdir | wc -l
13060                 etime=$(date +%s)
13061                 delta=$((etime - stime))
13062                 log "$lsx $i files without statahead: $delta sec"
13063                 lctl set_param llite.*.statahead_max=$max
13064
13065                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13066                         grep "statahead wrong:" | awk '{print $3}')
13067                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13068                 cancel_lru_locks mdc
13069                 cancel_lru_locks osc
13070                 stime=$(date +%s)
13071                 time $lsx $DIR/$tdir | wc -l
13072                 etime=$(date +%s)
13073                 delta_sa=$((etime - stime))
13074                 log "$lsx $i files with statahead: $delta_sa sec"
13075                 lctl get_param -n llite.*.statahead_stats
13076                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13077                         grep "statahead wrong:" | awk '{print $3}')
13078
13079                 [[ $swrong -lt $ewrong ]] &&
13080                         log "statahead was stopped, maybe too many locks held!"
13081                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13082
13083                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
13084                         max=$(lctl get_param -n llite.*.statahead_max |
13085                                 head -n 1)
13086                         lctl set_param -n llite.*.statahead_max 0
13087                         lctl get_param llite.*.statahead_max
13088                         cancel_lru_locks mdc
13089                         cancel_lru_locks osc
13090                         stime=$(date +%s)
13091                         time $lsx $DIR/$tdir | wc -l
13092                         etime=$(date +%s)
13093                         delta=$((etime - stime))
13094                         log "$lsx $i files again without statahead: $delta sec"
13095                         lctl set_param llite.*.statahead_max=$max
13096                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
13097                                 if [  $SLOWOK -eq 0 ]; then
13098                                         error "$lsx $i files is slower with statahead!"
13099                                 else
13100                                         log "$lsx $i files is slower with statahead!"
13101                                 fi
13102                                 break
13103                         fi
13104                 fi
13105
13106                 [ $delta -gt 20 ] && break
13107                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13108                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13109         done
13110         log "$lsx done"
13111
13112         stime=$(date +%s)
13113         rm -r $DIR/$tdir
13114         sync
13115         etime=$(date +%s)
13116         delta=$((etime - stime))
13117         log "rm -r $DIR/$tdir/: $delta seconds"
13118         log "rm done"
13119         lctl get_param -n llite.*.statahead_stats
13120 }
13121
13122 test_123aa() {
13123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13124
13125         test_123a_base "ls -l"
13126 }
13127 run_test 123aa "verify statahead work"
13128
13129 test_123ab() {
13130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13131
13132         statx_supported || skip_env "Test must be statx() syscall supported"
13133
13134         test_123a_base "$STATX -l"
13135 }
13136 run_test 123ab "verify statahead work by using statx"
13137
13138 test_123ac() {
13139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13140
13141         statx_supported || skip_env "Test must be statx() syscall supported"
13142
13143         local rpcs_before
13144         local rpcs_after
13145         local agl_before
13146         local agl_after
13147
13148         cancel_lru_locks $OSC
13149         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13150         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13151                 awk '/agl.total:/ {print $3}')
13152         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13153         test_123a_base "$STATX --cached=always -D"
13154         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13155                 awk '/agl.total:/ {print $3}')
13156         [ $agl_before -eq $agl_after ] ||
13157                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13158         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13159         [ $rpcs_after -eq $rpcs_before ] ||
13160                 error "$STATX should not send glimpse RPCs to $OSC"
13161 }
13162 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13163
13164 test_123b () { # statahead(bug 15027)
13165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13166
13167         test_mkdir $DIR/$tdir
13168         createmany -o $DIR/$tdir/$tfile-%d 1000
13169
13170         cancel_lru_locks mdc
13171         cancel_lru_locks osc
13172
13173 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13174         lctl set_param fail_loc=0x80000803
13175         ls -lR $DIR/$tdir > /dev/null
13176         log "ls done"
13177         lctl set_param fail_loc=0x0
13178         lctl get_param -n llite.*.statahead_stats
13179         rm -r $DIR/$tdir
13180         sync
13181
13182 }
13183 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13184
13185 test_123c() {
13186         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13187
13188         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13189         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13190         touch $DIR/$tdir.1/{1..3}
13191         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13192
13193         remount_client $MOUNT
13194
13195         $MULTIOP $DIR/$tdir.0 Q
13196
13197         # let statahead to complete
13198         ls -l $DIR/$tdir.0 > /dev/null
13199
13200         testid=$(echo $TESTNAME | tr '_' ' ')
13201         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13202                 error "statahead warning" || true
13203 }
13204 run_test 123c "Can not initialize inode warning on DNE statahead"
13205
13206 test_124a() {
13207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13208         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13209                 skip_env "no lru resize on server"
13210
13211         local NR=2000
13212
13213         test_mkdir $DIR/$tdir
13214
13215         log "create $NR files at $DIR/$tdir"
13216         createmany -o $DIR/$tdir/f $NR ||
13217                 error "failed to create $NR files in $DIR/$tdir"
13218
13219         cancel_lru_locks mdc
13220         ls -l $DIR/$tdir > /dev/null
13221
13222         local NSDIR=""
13223         local LRU_SIZE=0
13224         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13225                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13226                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13227                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13228                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13229                         log "NSDIR=$NSDIR"
13230                         log "NS=$(basename $NSDIR)"
13231                         break
13232                 fi
13233         done
13234
13235         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13236                 skip "Not enough cached locks created!"
13237         fi
13238         log "LRU=$LRU_SIZE"
13239
13240         local SLEEP=30
13241
13242         # We know that lru resize allows one client to hold $LIMIT locks
13243         # for 10h. After that locks begin to be killed by client.
13244         local MAX_HRS=10
13245         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13246         log "LIMIT=$LIMIT"
13247         if [ $LIMIT -lt $LRU_SIZE ]; then
13248                 skip "Limit is too small $LIMIT"
13249         fi
13250
13251         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13252         # killing locks. Some time was spent for creating locks. This means
13253         # that up to the moment of sleep finish we must have killed some of
13254         # them (10-100 locks). This depends on how fast ther were created.
13255         # Many of them were touched in almost the same moment and thus will
13256         # be killed in groups.
13257         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13258
13259         # Use $LRU_SIZE_B here to take into account real number of locks
13260         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13261         local LRU_SIZE_B=$LRU_SIZE
13262         log "LVF=$LVF"
13263         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13264         log "OLD_LVF=$OLD_LVF"
13265         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13266
13267         # Let's make sure that we really have some margin. Client checks
13268         # cached locks every 10 sec.
13269         SLEEP=$((SLEEP+20))
13270         log "Sleep ${SLEEP} sec"
13271         local SEC=0
13272         while ((SEC<$SLEEP)); do
13273                 echo -n "..."
13274                 sleep 5
13275                 SEC=$((SEC+5))
13276                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13277                 echo -n "$LRU_SIZE"
13278         done
13279         echo ""
13280         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13281         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13282
13283         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13284                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13285                 unlinkmany $DIR/$tdir/f $NR
13286                 return
13287         }
13288
13289         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13290         log "unlink $NR files at $DIR/$tdir"
13291         unlinkmany $DIR/$tdir/f $NR
13292 }
13293 run_test 124a "lru resize ======================================="
13294
13295 get_max_pool_limit()
13296 {
13297         local limit=$($LCTL get_param \
13298                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13299         local max=0
13300         for l in $limit; do
13301                 if [[ $l -gt $max ]]; then
13302                         max=$l
13303                 fi
13304         done
13305         echo $max
13306 }
13307
13308 test_124b() {
13309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13310         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13311                 skip_env "no lru resize on server"
13312
13313         LIMIT=$(get_max_pool_limit)
13314
13315         NR=$(($(default_lru_size)*20))
13316         if [[ $NR -gt $LIMIT ]]; then
13317                 log "Limit lock number by $LIMIT locks"
13318                 NR=$LIMIT
13319         fi
13320
13321         IFree=$(mdsrate_inodes_available)
13322         if [ $IFree -lt $NR ]; then
13323                 log "Limit lock number by $IFree inodes"
13324                 NR=$IFree
13325         fi
13326
13327         lru_resize_disable mdc
13328         test_mkdir -p $DIR/$tdir/disable_lru_resize
13329
13330         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13331         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13332         cancel_lru_locks mdc
13333         stime=`date +%s`
13334         PID=""
13335         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13336         PID="$PID $!"
13337         sleep 2
13338         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13339         PID="$PID $!"
13340         sleep 2
13341         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13342         PID="$PID $!"
13343         wait $PID
13344         etime=`date +%s`
13345         nolruresize_delta=$((etime-stime))
13346         log "ls -la time: $nolruresize_delta seconds"
13347         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13348         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13349
13350         lru_resize_enable mdc
13351         test_mkdir -p $DIR/$tdir/enable_lru_resize
13352
13353         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13354         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13355         cancel_lru_locks mdc
13356         stime=`date +%s`
13357         PID=""
13358         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13359         PID="$PID $!"
13360         sleep 2
13361         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13362         PID="$PID $!"
13363         sleep 2
13364         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13365         PID="$PID $!"
13366         wait $PID
13367         etime=`date +%s`
13368         lruresize_delta=$((etime-stime))
13369         log "ls -la time: $lruresize_delta seconds"
13370         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13371
13372         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13373                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13374         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13375                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13376         else
13377                 log "lru resize performs the same with no lru resize"
13378         fi
13379         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13380 }
13381 run_test 124b "lru resize (performance test) ======================="
13382
13383 test_124c() {
13384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13385         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13386                 skip_env "no lru resize on server"
13387
13388         # cache ununsed locks on client
13389         local nr=100
13390         cancel_lru_locks mdc
13391         test_mkdir $DIR/$tdir
13392         createmany -o $DIR/$tdir/f $nr ||
13393                 error "failed to create $nr files in $DIR/$tdir"
13394         ls -l $DIR/$tdir > /dev/null
13395
13396         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13397         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13398         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13399         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13400         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13401
13402         # set lru_max_age to 1 sec
13403         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13404         echo "sleep $((recalc_p * 2)) seconds..."
13405         sleep $((recalc_p * 2))
13406
13407         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13408         # restore lru_max_age
13409         $LCTL set_param -n $nsdir.lru_max_age $max_age
13410         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13411         unlinkmany $DIR/$tdir/f $nr
13412 }
13413 run_test 124c "LRUR cancel very aged locks"
13414
13415 test_124d() {
13416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13417         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13418                 skip_env "no lru resize on server"
13419
13420         # cache ununsed locks on client
13421         local nr=100
13422
13423         lru_resize_disable mdc
13424         stack_trap "lru_resize_enable mdc" EXIT
13425
13426         cancel_lru_locks mdc
13427
13428         # asynchronous object destroy at MDT could cause bl ast to client
13429         test_mkdir $DIR/$tdir
13430         createmany -o $DIR/$tdir/f $nr ||
13431                 error "failed to create $nr files in $DIR/$tdir"
13432         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13433
13434         ls -l $DIR/$tdir > /dev/null
13435
13436         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13437         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13438         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13439         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13440
13441         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13442
13443         # set lru_max_age to 1 sec
13444         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13445         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13446
13447         echo "sleep $((recalc_p * 2)) seconds..."
13448         sleep $((recalc_p * 2))
13449
13450         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13451
13452         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13453 }
13454 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13455
13456 test_125() { # 13358
13457         $LCTL get_param -n llite.*.client_type | grep -q local ||
13458                 skip "must run as local client"
13459         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13460                 skip_env "must have acl enabled"
13461         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13462
13463         test_mkdir $DIR/$tdir
13464         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13465         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13466         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13467 }
13468 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13469
13470 test_126() { # bug 12829/13455
13471         $GSS && skip_env "must run as gss disabled"
13472         $LCTL get_param -n llite.*.client_type | grep -q local ||
13473                 skip "must run as local client"
13474         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13475
13476         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13477         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13478         rm -f $DIR/$tfile
13479         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13480 }
13481 run_test 126 "check that the fsgid provided by the client is taken into account"
13482
13483 test_127a() { # bug 15521
13484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13485         local name count samp unit min max sum sumsq
13486
13487         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13488         echo "stats before reset"
13489         $LCTL get_param osc.*.stats
13490         $LCTL set_param osc.*.stats=0
13491         local fsize=$((2048 * 1024))
13492
13493         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13494         cancel_lru_locks osc
13495         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13496
13497         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13498         stack_trap "rm -f $TMP/$tfile.tmp"
13499         while read name count samp unit min max sum sumsq; do
13500                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13501                 [ ! $min ] && error "Missing min value for $name proc entry"
13502                 eval $name=$count || error "Wrong proc format"
13503
13504                 case $name in
13505                 read_bytes|write_bytes)
13506                         [[ "$unit" =~ "bytes" ]] ||
13507                                 error "unit is not 'bytes': $unit"
13508                         (( $min >= 4096 )) || error "min is too small: $min"
13509                         (( $min <= $fsize )) || error "min is too big: $min"
13510                         (( $max >= 4096 )) || error "max is too small: $max"
13511                         (( $max <= $fsize )) || error "max is too big: $max"
13512                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13513                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13514                                 error "sumsquare is too small: $sumsq"
13515                         (( $sumsq <= $fsize * $fsize )) ||
13516                                 error "sumsquare is too big: $sumsq"
13517                         ;;
13518                 ost_read|ost_write)
13519                         [[ "$unit" =~ "usec" ]] ||
13520                                 error "unit is not 'usec': $unit"
13521                         ;;
13522                 *)      ;;
13523                 esac
13524         done < $DIR/$tfile.tmp
13525
13526         #check that we actually got some stats
13527         [ "$read_bytes" ] || error "Missing read_bytes stats"
13528         [ "$write_bytes" ] || error "Missing write_bytes stats"
13529         [ "$read_bytes" != 0 ] || error "no read done"
13530         [ "$write_bytes" != 0 ] || error "no write done"
13531 }
13532 run_test 127a "verify the client stats are sane"
13533
13534 test_127b() { # bug LU-333
13535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13536         local name count samp unit min max sum sumsq
13537
13538         echo "stats before reset"
13539         $LCTL get_param llite.*.stats
13540         $LCTL set_param llite.*.stats=0
13541
13542         # perform 2 reads and writes so MAX is different from SUM.
13543         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13544         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13545         cancel_lru_locks osc
13546         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13547         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13548
13549         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13550         stack_trap "rm -f $TMP/$tfile.tmp"
13551         while read name count samp unit min max sum sumsq; do
13552                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13553                 eval $name=$count || error "Wrong proc format"
13554
13555                 case $name in
13556                 read_bytes|write_bytes)
13557                         [[ "$unit" =~ "bytes" ]] ||
13558                                 error "unit is not 'bytes': $unit"
13559                         (( $count == 2 )) || error "count is not 2: $count"
13560                         (( $min == $PAGE_SIZE )) ||
13561                                 error "min is not $PAGE_SIZE: $min"
13562                         (( $max == $PAGE_SIZE )) ||
13563                                 error "max is not $PAGE_SIZE: $max"
13564                         (( $sum == $PAGE_SIZE * 2 )) ||
13565                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13566                         ;;
13567                 read|write)
13568                         [[ "$unit" =~ "usec" ]] ||
13569                                 error "unit is not 'usec': $unit"
13570                         ;;
13571                 *)      ;;
13572                 esac
13573         done < $TMP/$tfile.tmp
13574
13575         #check that we actually got some stats
13576         [ "$read_bytes" ] || error "Missing read_bytes stats"
13577         [ "$write_bytes" ] || error "Missing write_bytes stats"
13578         [ "$read_bytes" != 0 ] || error "no read done"
13579         [ "$write_bytes" != 0 ] || error "no write done"
13580 }
13581 run_test 127b "verify the llite client stats are sane"
13582
13583 test_127c() { # LU-12394
13584         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13585         local size
13586         local bsize
13587         local reads
13588         local writes
13589         local count
13590
13591         $LCTL set_param llite.*.extents_stats=1
13592         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13593
13594         # Use two stripes so there is enough space in default config
13595         $LFS setstripe -c 2 $DIR/$tfile
13596
13597         # Extent stats start at 0-4K and go in power of two buckets
13598         # LL_HIST_START = 12 --> 2^12 = 4K
13599         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13600         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13601         # small configs
13602         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13603                 do
13604                 # Write and read, 2x each, second time at a non-zero offset
13605                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13606                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13607                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13608                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13609                 rm -f $DIR/$tfile
13610         done
13611
13612         $LCTL get_param llite.*.extents_stats
13613
13614         count=2
13615         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13616                 do
13617                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13618                                 grep -m 1 $bsize)
13619                 reads=$(echo $bucket | awk '{print $5}')
13620                 writes=$(echo $bucket | awk '{print $9}')
13621                 [ "$reads" -eq $count ] ||
13622                         error "$reads reads in < $bsize bucket, expect $count"
13623                 [ "$writes" -eq $count ] ||
13624                         error "$writes writes in < $bsize bucket, expect $count"
13625         done
13626
13627         # Test mmap write and read
13628         $LCTL set_param llite.*.extents_stats=c
13629         size=512
13630         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13631         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13632         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13633
13634         $LCTL get_param llite.*.extents_stats
13635
13636         count=$(((size*1024) / PAGE_SIZE))
13637
13638         bsize=$((2 * PAGE_SIZE / 1024))K
13639
13640         bucket=$($LCTL get_param -n llite.*.extents_stats |
13641                         grep -m 1 $bsize)
13642         reads=$(echo $bucket | awk '{print $5}')
13643         writes=$(echo $bucket | awk '{print $9}')
13644         # mmap writes fault in the page first, creating an additonal read
13645         [ "$reads" -eq $((2 * count)) ] ||
13646                 error "$reads reads in < $bsize bucket, expect $count"
13647         [ "$writes" -eq $count ] ||
13648                 error "$writes writes in < $bsize bucket, expect $count"
13649 }
13650 run_test 127c "test llite extent stats with regular & mmap i/o"
13651
13652 test_128() { # bug 15212
13653         touch $DIR/$tfile
13654         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13655                 find $DIR/$tfile
13656                 find $DIR/$tfile
13657         EOF
13658
13659         result=$(grep error $TMP/$tfile.log)
13660         rm -f $DIR/$tfile $TMP/$tfile.log
13661         [ -z "$result" ] ||
13662                 error "consecutive find's under interactive lfs failed"
13663 }
13664 run_test 128 "interactive lfs for 2 consecutive find's"
13665
13666 set_dir_limits () {
13667         local mntdev
13668         local canondev
13669         local node
13670
13671         local ldproc=/proc/fs/ldiskfs
13672         local facets=$(get_facets MDS)
13673
13674         for facet in ${facets//,/ }; do
13675                 canondev=$(ldiskfs_canon \
13676                            *.$(convert_facet2label $facet).mntdev $facet)
13677                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13678                         ldproc=/sys/fs/ldiskfs
13679                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13680                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13681         done
13682 }
13683
13684 check_mds_dmesg() {
13685         local facets=$(get_facets MDS)
13686         for facet in ${facets//,/ }; do
13687                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13688         done
13689         return 1
13690 }
13691
13692 test_129() {
13693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13694         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13695                 skip "Need MDS version with at least 2.5.56"
13696         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13697                 skip_env "ldiskfs only test"
13698         fi
13699         remote_mds_nodsh && skip "remote MDS with nodsh"
13700
13701         local ENOSPC=28
13702         local has_warning=false
13703
13704         rm -rf $DIR/$tdir
13705         mkdir -p $DIR/$tdir
13706
13707         # block size of mds1
13708         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13709         set_dir_limits $maxsize $((maxsize * 6 / 8))
13710         stack_trap "set_dir_limits 0 0"
13711         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13712         local dirsize=$(stat -c%s "$DIR/$tdir")
13713         local nfiles=0
13714         while (( $dirsize <= $maxsize )); do
13715                 $MCREATE $DIR/$tdir/file_base_$nfiles
13716                 rc=$?
13717                 # check two errors:
13718                 # ENOSPC for ext4 max_dir_size, which has been used since
13719                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13720                 if (( rc == ENOSPC )); then
13721                         set_dir_limits 0 0
13722                         echo "rc=$rc returned as expected after $nfiles files"
13723
13724                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13725                                 error "create failed w/o dir size limit"
13726
13727                         # messages may be rate limited if test is run repeatedly
13728                         check_mds_dmesg '"is approaching max"' ||
13729                                 echo "warning message should be output"
13730                         check_mds_dmesg '"has reached max"' ||
13731                                 echo "reached message should be output"
13732
13733                         dirsize=$(stat -c%s "$DIR/$tdir")
13734
13735                         [[ $dirsize -ge $maxsize ]] && return 0
13736                         error "dirsize $dirsize < $maxsize after $nfiles files"
13737                 elif (( rc != 0 )); then
13738                         break
13739                 fi
13740                 nfiles=$((nfiles + 1))
13741                 dirsize=$(stat -c%s "$DIR/$tdir")
13742         done
13743
13744         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13745 }
13746 run_test 129 "test directory size limit ========================"
13747
13748 OLDIFS="$IFS"
13749 cleanup_130() {
13750         trap 0
13751         IFS="$OLDIFS"
13752 }
13753
13754 test_130a() {
13755         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13756         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13757
13758         trap cleanup_130 EXIT RETURN
13759
13760         local fm_file=$DIR/$tfile
13761         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13762         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13763                 error "dd failed for $fm_file"
13764
13765         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13766         filefrag -ves $fm_file
13767         RC=$?
13768         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13769                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13770         [ $RC != 0 ] && error "filefrag $fm_file failed"
13771
13772         filefrag_op=$(filefrag -ve -k $fm_file |
13773                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13774         lun=$($LFS getstripe -i $fm_file)
13775
13776         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13777         IFS=$'\n'
13778         tot_len=0
13779         for line in $filefrag_op
13780         do
13781                 frag_lun=`echo $line | cut -d: -f5`
13782                 ext_len=`echo $line | cut -d: -f4`
13783                 if (( $frag_lun != $lun )); then
13784                         cleanup_130
13785                         error "FIEMAP on 1-stripe file($fm_file) failed"
13786                         return
13787                 fi
13788                 (( tot_len += ext_len ))
13789         done
13790
13791         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13792                 cleanup_130
13793                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13794                 return
13795         fi
13796
13797         cleanup_130
13798
13799         echo "FIEMAP on single striped file succeeded"
13800 }
13801 run_test 130a "FIEMAP (1-stripe file)"
13802
13803 test_130b() {
13804         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13805
13806         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13807         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13808
13809         trap cleanup_130 EXIT RETURN
13810
13811         local fm_file=$DIR/$tfile
13812         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13813                         error "setstripe on $fm_file"
13814         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13815                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13816
13817         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13818                 error "dd failed on $fm_file"
13819
13820         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13821         filefrag_op=$(filefrag -ve -k $fm_file |
13822                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13823
13824         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13825                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13826
13827         IFS=$'\n'
13828         tot_len=0
13829         num_luns=1
13830         for line in $filefrag_op
13831         do
13832                 frag_lun=$(echo $line | cut -d: -f5 |
13833                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13834                 ext_len=$(echo $line | cut -d: -f4)
13835                 if (( $frag_lun != $last_lun )); then
13836                         if (( tot_len != 1024 )); then
13837                                 cleanup_130
13838                                 error "FIEMAP on $fm_file failed; returned " \
13839                                 "len $tot_len for OST $last_lun instead of 1024"
13840                                 return
13841                         else
13842                                 (( num_luns += 1 ))
13843                                 tot_len=0
13844                         fi
13845                 fi
13846                 (( tot_len += ext_len ))
13847                 last_lun=$frag_lun
13848         done
13849         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13850                 cleanup_130
13851                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13852                         "luns or wrong len for OST $last_lun"
13853                 return
13854         fi
13855
13856         cleanup_130
13857
13858         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13859 }
13860 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13861
13862 test_130c() {
13863         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13864
13865         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13866         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13867
13868         trap cleanup_130 EXIT RETURN
13869
13870         local fm_file=$DIR/$tfile
13871         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13872         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13873                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13874
13875         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13876                         error "dd failed on $fm_file"
13877
13878         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13879         filefrag_op=$(filefrag -ve -k $fm_file |
13880                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13881
13882         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13883                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13884
13885         IFS=$'\n'
13886         tot_len=0
13887         num_luns=1
13888         for line in $filefrag_op
13889         do
13890                 frag_lun=$(echo $line | cut -d: -f5 |
13891                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13892                 ext_len=$(echo $line | cut -d: -f4)
13893                 if (( $frag_lun != $last_lun )); then
13894                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13895                         if (( logical != 512 )); then
13896                                 cleanup_130
13897                                 error "FIEMAP on $fm_file failed; returned " \
13898                                 "logical start for lun $logical instead of 512"
13899                                 return
13900                         fi
13901                         if (( tot_len != 512 )); then
13902                                 cleanup_130
13903                                 error "FIEMAP on $fm_file failed; returned " \
13904                                 "len $tot_len for OST $last_lun instead of 1024"
13905                                 return
13906                         else
13907                                 (( num_luns += 1 ))
13908                                 tot_len=0
13909                         fi
13910                 fi
13911                 (( tot_len += ext_len ))
13912                 last_lun=$frag_lun
13913         done
13914         if (( num_luns != 2 || tot_len != 512 )); then
13915                 cleanup_130
13916                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13917                         "luns or wrong len for OST $last_lun"
13918                 return
13919         fi
13920
13921         cleanup_130
13922
13923         echo "FIEMAP on 2-stripe file with hole succeeded"
13924 }
13925 run_test 130c "FIEMAP (2-stripe file with hole)"
13926
13927 test_130d() {
13928         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13929
13930         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13931         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13932
13933         trap cleanup_130 EXIT RETURN
13934
13935         local fm_file=$DIR/$tfile
13936         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13937                         error "setstripe on $fm_file"
13938         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13939                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13940
13941         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13942         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13943                 error "dd failed on $fm_file"
13944
13945         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13946         filefrag_op=$(filefrag -ve -k $fm_file |
13947                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13948
13949         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13950                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13951
13952         IFS=$'\n'
13953         tot_len=0
13954         num_luns=1
13955         for line in $filefrag_op
13956         do
13957                 frag_lun=$(echo $line | cut -d: -f5 |
13958                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13959                 ext_len=$(echo $line | cut -d: -f4)
13960                 if (( $frag_lun != $last_lun )); then
13961                         if (( tot_len != 1024 )); then
13962                                 cleanup_130
13963                                 error "FIEMAP on $fm_file failed; returned " \
13964                                 "len $tot_len for OST $last_lun instead of 1024"
13965                                 return
13966                         else
13967                                 (( num_luns += 1 ))
13968                                 tot_len=0
13969                         fi
13970                 fi
13971                 (( tot_len += ext_len ))
13972                 last_lun=$frag_lun
13973         done
13974         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13975                 cleanup_130
13976                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13977                         "luns or wrong len for OST $last_lun"
13978                 return
13979         fi
13980
13981         cleanup_130
13982
13983         echo "FIEMAP on N-stripe file succeeded"
13984 }
13985 run_test 130d "FIEMAP (N-stripe file)"
13986
13987 test_130e() {
13988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13989
13990         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13991         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13992
13993         trap cleanup_130 EXIT RETURN
13994
13995         local fm_file=$DIR/$tfile
13996         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13997
13998         NUM_BLKS=512
13999         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
14000         for ((i = 0; i < $NUM_BLKS; i++)); do
14001                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14002                         conv=notrunc > /dev/null 2>&1
14003         done
14004
14005         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14006         filefrag_op=$(filefrag -ve -k $fm_file |
14007                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14008
14009         last_lun=$(echo $filefrag_op | cut -d: -f5)
14010
14011         IFS=$'\n'
14012         tot_len=0
14013         num_luns=1
14014         for line in $filefrag_op; do
14015                 frag_lun=$(echo $line | cut -d: -f5)
14016                 ext_len=$(echo $line | cut -d: -f4)
14017                 if [[ "$frag_lun" != "$last_lun" ]]; then
14018                         if (( tot_len != $EXPECTED_LEN )); then
14019                                 cleanup_130
14020                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
14021                         else
14022                                 (( num_luns += 1 ))
14023                                 tot_len=0
14024                         fi
14025                 fi
14026                 (( tot_len += ext_len ))
14027                 last_lun=$frag_lun
14028         done
14029         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
14030                 cleanup_130
14031                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
14032         fi
14033
14034         echo "FIEMAP with continuation calls succeeded"
14035 }
14036 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14037
14038 test_130f() {
14039         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14040         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
14041
14042         local fm_file=$DIR/$tfile
14043         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14044                 error "multiop create with lov_delay_create on $fm_file"
14045
14046         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14047         filefrag_extents=$(filefrag -vek $fm_file |
14048                            awk '/extents? found/ { print $2 }')
14049         if [[ "$filefrag_extents" != "0" ]]; then
14050                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14051         fi
14052
14053         rm -f $fm_file
14054 }
14055 run_test 130f "FIEMAP (unstriped file)"
14056
14057 test_130g() {
14058         local file=$DIR/$tfile
14059         local nr=$((OSTCOUNT * 100))
14060
14061         $LFS setstripe -C $nr $file ||
14062                 error "failed to setstripe -C $nr $file"
14063
14064         dd if=/dev/zero of=$file count=$nr bs=1M
14065         sync
14066         nr=$($LFS getstripe -c $file)
14067
14068         local extents=$(filefrag -v $file |
14069                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14070
14071         echo "filefrag list $extents extents in file with stripecount $nr"
14072         if (( extents < nr )); then
14073                 $LFS getstripe $file
14074                 filefrag -v $file
14075                 error "filefrag printed $extents < $nr extents"
14076         fi
14077
14078         rm -f $file
14079 }
14080 run_test 130g "FIEMAP (overstripe file)"
14081
14082 # Test for writev/readv
14083 test_131a() {
14084         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14085                 error "writev test failed"
14086         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14087                 error "readv failed"
14088         rm -f $DIR/$tfile
14089 }
14090 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14091
14092 test_131b() {
14093         local fsize=$((524288 + 1048576 + 1572864))
14094         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14095                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14096                         error "append writev test failed"
14097
14098         ((fsize += 1572864 + 1048576))
14099         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14100                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14101                         error "append writev test failed"
14102         rm -f $DIR/$tfile
14103 }
14104 run_test 131b "test append writev"
14105
14106 test_131c() {
14107         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14108         error "NOT PASS"
14109 }
14110 run_test 131c "test read/write on file w/o objects"
14111
14112 test_131d() {
14113         rwv -f $DIR/$tfile -w -n 1 1572864
14114         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14115         if [ "$NOB" != 1572864 ]; then
14116                 error "Short read filed: read $NOB bytes instead of 1572864"
14117         fi
14118         rm -f $DIR/$tfile
14119 }
14120 run_test 131d "test short read"
14121
14122 test_131e() {
14123         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14124         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14125         error "read hitting hole failed"
14126         rm -f $DIR/$tfile
14127 }
14128 run_test 131e "test read hitting hole"
14129
14130 check_stats() {
14131         local facet=$1
14132         local op=$2
14133         local want=${3:-0}
14134         local res
14135
14136         case $facet in
14137         mds*) res=$(do_facet $facet \
14138                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14139                  ;;
14140         ost*) res=$(do_facet $facet \
14141                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14142                  ;;
14143         *) error "Wrong facet '$facet'" ;;
14144         esac
14145         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14146         # if the argument $3 is zero, it means any stat increment is ok.
14147         if [[ $want -gt 0 ]]; then
14148                 local count=$(echo $res | awk '{ print $2 }')
14149                 [[ $count -ne $want ]] &&
14150                         error "The $op counter on $facet is $count, not $want"
14151         fi
14152 }
14153
14154 test_133a() {
14155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14156         remote_ost_nodsh && skip "remote OST with nodsh"
14157         remote_mds_nodsh && skip "remote MDS with nodsh"
14158         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14159                 skip_env "MDS doesn't support rename stats"
14160
14161         local testdir=$DIR/${tdir}/stats_testdir
14162
14163         mkdir -p $DIR/${tdir}
14164
14165         # clear stats.
14166         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14167         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14168
14169         # verify mdt stats first.
14170         mkdir ${testdir} || error "mkdir failed"
14171         check_stats $SINGLEMDS "mkdir" 1
14172         touch ${testdir}/${tfile} || error "touch failed"
14173         check_stats $SINGLEMDS "open" 1
14174         check_stats $SINGLEMDS "close" 1
14175         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14176                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14177                 check_stats $SINGLEMDS "mknod" 2
14178         }
14179         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14180         check_stats $SINGLEMDS "unlink" 1
14181         rm -f ${testdir}/${tfile} || error "file remove failed"
14182         check_stats $SINGLEMDS "unlink" 2
14183
14184         # remove working dir and check mdt stats again.
14185         rmdir ${testdir} || error "rmdir failed"
14186         check_stats $SINGLEMDS "rmdir" 1
14187
14188         local testdir1=$DIR/${tdir}/stats_testdir1
14189         mkdir -p ${testdir}
14190         mkdir -p ${testdir1}
14191         touch ${testdir1}/test1
14192         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14193         check_stats $SINGLEMDS "crossdir_rename" 1
14194
14195         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14196         check_stats $SINGLEMDS "samedir_rename" 1
14197
14198         rm -rf $DIR/${tdir}
14199 }
14200 run_test 133a "Verifying MDT stats ========================================"
14201
14202 test_133b() {
14203         local res
14204
14205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14206         remote_ost_nodsh && skip "remote OST with nodsh"
14207         remote_mds_nodsh && skip "remote MDS with nodsh"
14208
14209         local testdir=$DIR/${tdir}/stats_testdir
14210
14211         mkdir -p ${testdir} || error "mkdir failed"
14212         touch ${testdir}/${tfile} || error "touch failed"
14213         cancel_lru_locks mdc
14214
14215         # clear stats.
14216         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14217         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14218
14219         # extra mdt stats verification.
14220         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14221         check_stats $SINGLEMDS "setattr" 1
14222         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14223         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14224         then            # LU-1740
14225                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14226                 check_stats $SINGLEMDS "getattr" 1
14227         fi
14228         rm -rf $DIR/${tdir}
14229
14230         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14231         # so the check below is not reliable
14232         [ $MDSCOUNT -eq 1 ] || return 0
14233
14234         # Sleep to avoid a cached response.
14235         #define OBD_STATFS_CACHE_SECONDS 1
14236         sleep 2
14237         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14238         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14239         $LFS df || error "lfs failed"
14240         check_stats $SINGLEMDS "statfs" 1
14241
14242         # check aggregated statfs (LU-10018)
14243         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14244                 return 0
14245         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14246                 return 0
14247         sleep 2
14248         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14249         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14250         df $DIR
14251         check_stats $SINGLEMDS "statfs" 1
14252
14253         # We want to check that the client didn't send OST_STATFS to
14254         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14255         # extra care is needed here.
14256         if remote_mds; then
14257                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14258                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14259
14260                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14261                 [ "$res" ] && error "OST got STATFS"
14262         fi
14263
14264         return 0
14265 }
14266 run_test 133b "Verifying extra MDT stats =================================="
14267
14268 test_133c() {
14269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14270         remote_ost_nodsh && skip "remote OST with nodsh"
14271         remote_mds_nodsh && skip "remote MDS with nodsh"
14272
14273         local testdir=$DIR/$tdir/stats_testdir
14274
14275         test_mkdir -p $testdir
14276
14277         # verify obdfilter stats.
14278         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14279         sync
14280         cancel_lru_locks osc
14281         wait_delete_completed
14282
14283         # clear stats.
14284         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14285         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14286
14287         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14288                 error "dd failed"
14289         sync
14290         cancel_lru_locks osc
14291         check_stats ost1 "write" 1
14292
14293         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14294         check_stats ost1 "read" 1
14295
14296         > $testdir/$tfile || error "truncate failed"
14297         check_stats ost1 "punch" 1
14298
14299         rm -f $testdir/$tfile || error "file remove failed"
14300         wait_delete_completed
14301         check_stats ost1 "destroy" 1
14302
14303         rm -rf $DIR/$tdir
14304 }
14305 run_test 133c "Verifying OST stats ========================================"
14306
14307 order_2() {
14308         local value=$1
14309         local orig=$value
14310         local order=1
14311
14312         while [ $value -ge 2 ]; do
14313                 order=$((order*2))
14314                 value=$((value/2))
14315         done
14316
14317         if [ $orig -gt $order ]; then
14318                 order=$((order*2))
14319         fi
14320         echo $order
14321 }
14322
14323 size_in_KMGT() {
14324     local value=$1
14325     local size=('K' 'M' 'G' 'T');
14326     local i=0
14327     local size_string=$value
14328
14329     while [ $value -ge 1024 ]; do
14330         if [ $i -gt 3 ]; then
14331             #T is the biggest unit we get here, if that is bigger,
14332             #just return XXXT
14333             size_string=${value}T
14334             break
14335         fi
14336         value=$((value >> 10))
14337         if [ $value -lt 1024 ]; then
14338             size_string=${value}${size[$i]}
14339             break
14340         fi
14341         i=$((i + 1))
14342     done
14343
14344     echo $size_string
14345 }
14346
14347 get_rename_size() {
14348         local size=$1
14349         local context=${2:-.}
14350         local sample=$(do_facet $SINGLEMDS $LCTL \
14351                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14352                 grep -A1 $context |
14353                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14354         echo $sample
14355 }
14356
14357 test_133d() {
14358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14359         remote_ost_nodsh && skip "remote OST with nodsh"
14360         remote_mds_nodsh && skip "remote MDS with nodsh"
14361         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14362                 skip_env "MDS doesn't support rename stats"
14363
14364         local testdir1=$DIR/${tdir}/stats_testdir1
14365         local testdir2=$DIR/${tdir}/stats_testdir2
14366         mkdir -p $DIR/${tdir}
14367
14368         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14369
14370         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14371         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14372
14373         createmany -o $testdir1/test 512 || error "createmany failed"
14374
14375         # check samedir rename size
14376         mv ${testdir1}/test0 ${testdir1}/test_0
14377
14378         local testdir1_size=$(ls -l $DIR/${tdir} |
14379                 awk '/stats_testdir1/ {print $5}')
14380         local testdir2_size=$(ls -l $DIR/${tdir} |
14381                 awk '/stats_testdir2/ {print $5}')
14382
14383         testdir1_size=$(order_2 $testdir1_size)
14384         testdir2_size=$(order_2 $testdir2_size)
14385
14386         testdir1_size=$(size_in_KMGT $testdir1_size)
14387         testdir2_size=$(size_in_KMGT $testdir2_size)
14388
14389         echo "source rename dir size: ${testdir1_size}"
14390         echo "target rename dir size: ${testdir2_size}"
14391
14392         local cmd="do_facet $SINGLEMDS $LCTL "
14393         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14394
14395         eval $cmd || error "$cmd failed"
14396         local samedir=$($cmd | grep 'same_dir')
14397         local same_sample=$(get_rename_size $testdir1_size)
14398         [ -z "$samedir" ] && error "samedir_rename_size count error"
14399         [[ $same_sample -eq 1 ]] ||
14400                 error "samedir_rename_size error $same_sample"
14401         echo "Check same dir rename stats success"
14402
14403         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14404
14405         # check crossdir rename size
14406         mv ${testdir1}/test_0 ${testdir2}/test_0
14407
14408         testdir1_size=$(ls -l $DIR/${tdir} |
14409                 awk '/stats_testdir1/ {print $5}')
14410         testdir2_size=$(ls -l $DIR/${tdir} |
14411                 awk '/stats_testdir2/ {print $5}')
14412
14413         testdir1_size=$(order_2 $testdir1_size)
14414         testdir2_size=$(order_2 $testdir2_size)
14415
14416         testdir1_size=$(size_in_KMGT $testdir1_size)
14417         testdir2_size=$(size_in_KMGT $testdir2_size)
14418
14419         echo "source rename dir size: ${testdir1_size}"
14420         echo "target rename dir size: ${testdir2_size}"
14421
14422         eval $cmd || error "$cmd failed"
14423         local crossdir=$($cmd | grep 'crossdir')
14424         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14425         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14426         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14427         [[ $src_sample -eq 1 ]] ||
14428                 error "crossdir_rename_size error $src_sample"
14429         [[ $tgt_sample -eq 1 ]] ||
14430                 error "crossdir_rename_size error $tgt_sample"
14431         echo "Check cross dir rename stats success"
14432         rm -rf $DIR/${tdir}
14433 }
14434 run_test 133d "Verifying rename_stats ========================================"
14435
14436 test_133e() {
14437         remote_mds_nodsh && skip "remote MDS with nodsh"
14438         remote_ost_nodsh && skip "remote OST with nodsh"
14439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14440
14441         local testdir=$DIR/${tdir}/stats_testdir
14442         local ctr f0 f1 bs=32768 count=42 sum
14443
14444         mkdir -p ${testdir} || error "mkdir failed"
14445
14446         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14447
14448         for ctr in {write,read}_bytes; do
14449                 sync
14450                 cancel_lru_locks osc
14451
14452                 do_facet ost1 $LCTL set_param -n \
14453                         "obdfilter.*.exports.clear=clear"
14454
14455                 if [ $ctr = write_bytes ]; then
14456                         f0=/dev/zero
14457                         f1=${testdir}/${tfile}
14458                 else
14459                         f0=${testdir}/${tfile}
14460                         f1=/dev/null
14461                 fi
14462
14463                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14464                         error "dd failed"
14465                 sync
14466                 cancel_lru_locks osc
14467
14468                 sum=$(do_facet ost1 $LCTL get_param \
14469                         "obdfilter.*.exports.*.stats" |
14470                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14471                                 $1 == ctr { sum += $7 }
14472                                 END { printf("%0.0f", sum) }')
14473
14474                 if ((sum != bs * count)); then
14475                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14476                 fi
14477         done
14478
14479         rm -rf $DIR/${tdir}
14480 }
14481 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14482
14483 test_133f() {
14484         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14485                 skip "too old lustre for get_param -R ($facet_ver)"
14486
14487         # verifying readability.
14488         $LCTL get_param -R '*' &> /dev/null
14489
14490         # Verifing writability with badarea_io.
14491         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14492         local skipped_params='force_lbug|changelog_mask|daemon_file'
14493         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14494                 egrep -v "$skipped_params" |
14495                 xargs -n 1 find $proc_dirs -name |
14496                 xargs -n 1 badarea_io ||
14497                 error "client badarea_io failed"
14498
14499         # remount the FS in case writes/reads /proc break the FS
14500         cleanup || error "failed to unmount"
14501         setup || error "failed to setup"
14502 }
14503 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14504
14505 test_133g() {
14506         remote_mds_nodsh && skip "remote MDS with nodsh"
14507         remote_ost_nodsh && skip "remote OST with nodsh"
14508
14509         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14510         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14511         local facet
14512         for facet in mds1 ost1; do
14513                 local facet_ver=$(lustre_version_code $facet)
14514                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14515                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14516                 else
14517                         log "$facet: too old lustre for get_param -R"
14518                 fi
14519                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14520                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14521                                 tr -d = | egrep -v $skipped_params |
14522                                 xargs -n 1 find $proc_dirs -name |
14523                                 xargs -n 1 badarea_io" ||
14524                                         error "$facet badarea_io failed"
14525                 else
14526                         skip_noexit "$facet: too old lustre for get_param -R"
14527                 fi
14528         done
14529
14530         # remount the FS in case writes/reads /proc break the FS
14531         cleanup || error "failed to unmount"
14532         setup || error "failed to setup"
14533 }
14534 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14535
14536 test_133h() {
14537         remote_mds_nodsh && skip "remote MDS with nodsh"
14538         remote_ost_nodsh && skip "remote OST with nodsh"
14539         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14540                 skip "Need MDS version at least 2.9.54"
14541
14542         local facet
14543         for facet in client mds1 ost1; do
14544                 # Get the list of files that are missing the terminating newline
14545                 local plist=$(do_facet $facet
14546                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14547                 local ent
14548                 for ent in $plist; do
14549                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14550                                 awk -v FS='\v' -v RS='\v\v' \
14551                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14552                                         print FILENAME}'" 2>/dev/null)
14553                         [ -z $missing ] || {
14554                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14555                                 error "file does not end with newline: $facet-$ent"
14556                         }
14557                 done
14558         done
14559 }
14560 run_test 133h "Proc files should end with newlines"
14561
14562 test_134a() {
14563         remote_mds_nodsh && skip "remote MDS with nodsh"
14564         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14565                 skip "Need MDS version at least 2.7.54"
14566
14567         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14568         cancel_lru_locks mdc
14569
14570         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14571         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14572         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14573
14574         local nr=1000
14575         createmany -o $DIR/$tdir/f $nr ||
14576                 error "failed to create $nr files in $DIR/$tdir"
14577         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14578
14579         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14580         do_facet mds1 $LCTL set_param fail_loc=0x327
14581         do_facet mds1 $LCTL set_param fail_val=500
14582         touch $DIR/$tdir/m
14583
14584         echo "sleep 10 seconds ..."
14585         sleep 10
14586         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14587
14588         do_facet mds1 $LCTL set_param fail_loc=0
14589         do_facet mds1 $LCTL set_param fail_val=0
14590         [ $lck_cnt -lt $unused ] ||
14591                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14592
14593         rm $DIR/$tdir/m
14594         unlinkmany $DIR/$tdir/f $nr
14595 }
14596 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14597
14598 test_134b() {
14599         remote_mds_nodsh && skip "remote MDS with nodsh"
14600         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14601                 skip "Need MDS version at least 2.7.54"
14602
14603         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14604         cancel_lru_locks mdc
14605
14606         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14607                         ldlm.lock_reclaim_threshold_mb)
14608         # disable reclaim temporarily
14609         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14610
14611         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14612         do_facet mds1 $LCTL set_param fail_loc=0x328
14613         do_facet mds1 $LCTL set_param fail_val=500
14614
14615         $LCTL set_param debug=+trace
14616
14617         local nr=600
14618         createmany -o $DIR/$tdir/f $nr &
14619         local create_pid=$!
14620
14621         echo "Sleep $TIMEOUT seconds ..."
14622         sleep $TIMEOUT
14623         if ! ps -p $create_pid  > /dev/null 2>&1; then
14624                 do_facet mds1 $LCTL set_param fail_loc=0
14625                 do_facet mds1 $LCTL set_param fail_val=0
14626                 do_facet mds1 $LCTL set_param \
14627                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14628                 error "createmany finished incorrectly!"
14629         fi
14630         do_facet mds1 $LCTL set_param fail_loc=0
14631         do_facet mds1 $LCTL set_param fail_val=0
14632         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14633         wait $create_pid || return 1
14634
14635         unlinkmany $DIR/$tdir/f $nr
14636 }
14637 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14638
14639 test_135() {
14640         remote_mds_nodsh && skip "remote MDS with nodsh"
14641         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14642                 skip "Need MDS version at least 2.13.50"
14643         local fname
14644
14645         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14646
14647 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14648         #set only one record at plain llog
14649         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14650
14651         #fill already existed plain llog each 64767
14652         #wrapping whole catalog
14653         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14654
14655         createmany -o $DIR/$tdir/$tfile_ 64700
14656         for (( i = 0; i < 64700; i = i + 2 ))
14657         do
14658                 rm $DIR/$tdir/$tfile_$i &
14659                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14660                 local pid=$!
14661                 wait $pid
14662         done
14663
14664         #waiting osp synchronization
14665         wait_delete_completed
14666 }
14667 run_test 135 "Race catalog processing"
14668
14669 test_136() {
14670         remote_mds_nodsh && skip "remote MDS with nodsh"
14671         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14672                 skip "Need MDS version at least 2.13.50"
14673         local fname
14674
14675         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14676         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14677         #set only one record at plain llog
14678 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14679         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14680
14681         #fill already existed 2 plain llogs each 64767
14682         #wrapping whole catalog
14683         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14684         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14685         wait_delete_completed
14686
14687         createmany -o $DIR/$tdir/$tfile_ 10
14688         sleep 25
14689
14690         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14691         for (( i = 0; i < 10; i = i + 3 ))
14692         do
14693                 rm $DIR/$tdir/$tfile_$i &
14694                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14695                 local pid=$!
14696                 wait $pid
14697                 sleep 7
14698                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14699         done
14700
14701         #waiting osp synchronization
14702         wait_delete_completed
14703 }
14704 run_test 136 "Race catalog processing 2"
14705
14706 test_140() { #bug-17379
14707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14708
14709         test_mkdir $DIR/$tdir
14710         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14711         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14712
14713         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14714         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14715         local i=0
14716         while i=$((i + 1)); do
14717                 test_mkdir $i
14718                 cd $i || error "Changing to $i"
14719                 ln -s ../stat stat || error "Creating stat symlink"
14720                 # Read the symlink until ELOOP present,
14721                 # not LBUGing the system is considered success,
14722                 # we didn't overrun the stack.
14723                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14724                 if [ $ret -ne 0 ]; then
14725                         if [ $ret -eq 40 ]; then
14726                                 break  # -ELOOP
14727                         else
14728                                 error "Open stat symlink"
14729                                         return
14730                         fi
14731                 fi
14732         done
14733         i=$((i - 1))
14734         echo "The symlink depth = $i"
14735         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14736                 error "Invalid symlink depth"
14737
14738         # Test recursive symlink
14739         ln -s symlink_self symlink_self
14740         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14741         echo "open symlink_self returns $ret"
14742         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14743 }
14744 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14745
14746 test_150a() {
14747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14748
14749         local TF="$TMP/$tfile"
14750
14751         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14752         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14753         cp $TF $DIR/$tfile
14754         cancel_lru_locks $OSC
14755         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14756         remount_client $MOUNT
14757         df -P $MOUNT
14758         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14759
14760         $TRUNCATE $TF 6000
14761         $TRUNCATE $DIR/$tfile 6000
14762         cancel_lru_locks $OSC
14763         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14764
14765         echo "12345" >>$TF
14766         echo "12345" >>$DIR/$tfile
14767         cancel_lru_locks $OSC
14768         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14769
14770         echo "12345" >>$TF
14771         echo "12345" >>$DIR/$tfile
14772         cancel_lru_locks $OSC
14773         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14774 }
14775 run_test 150a "truncate/append tests"
14776
14777 test_150b() {
14778         check_set_fallocate_or_skip
14779
14780         touch $DIR/$tfile
14781         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14782         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14783 }
14784 run_test 150b "Verify fallocate (prealloc) functionality"
14785
14786 test_150bb() {
14787         check_set_fallocate_or_skip
14788
14789         touch $DIR/$tfile
14790         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14791         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14792         > $DIR/$tfile
14793         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14794         # precomputed md5sum for 20MB of zeroes
14795         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14796         local sum=($(md5sum $DIR/$tfile))
14797
14798         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14799
14800         check_set_fallocate 1
14801
14802         > $DIR/$tfile
14803         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14804         sum=($(md5sum $DIR/$tfile))
14805
14806         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14807 }
14808 run_test 150bb "Verify fallocate modes both zero space"
14809
14810 test_150c() {
14811         check_set_fallocate_or_skip
14812         local striping="-c2"
14813
14814         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14815         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14816         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14817         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14818         local want=$((OSTCOUNT * 1048576))
14819
14820         # Must allocate all requested space, not more than 5% extra
14821         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14822                 error "bytes $bytes is not $want"
14823
14824         rm -f $DIR/$tfile
14825
14826         echo "verify fallocate on PFL file"
14827
14828         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14829
14830         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14831                 error "Create $DIR/$tfile failed"
14832         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14833         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14834         want=$((512 * 1048576))
14835
14836         # Must allocate all requested space, not more than 5% extra
14837         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14838                 error "bytes $bytes is not $want"
14839 }
14840 run_test 150c "Verify fallocate Size and Blocks"
14841
14842 test_150d() {
14843         check_set_fallocate_or_skip
14844         local striping="-c2"
14845
14846         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14847
14848         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14849         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14850                 error "setstripe failed"
14851         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14852         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14853         local want=$((OSTCOUNT * 1048576))
14854
14855         # Must allocate all requested space, not more than 5% extra
14856         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14857                 error "bytes $bytes is not $want"
14858 }
14859 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14860
14861 test_150e() {
14862         check_set_fallocate_or_skip
14863
14864         echo "df before:"
14865         $LFS df
14866         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14867         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14868                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14869
14870         # Find OST with Minimum Size
14871         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14872                        sort -un | head -1)
14873
14874         # Get 100MB per OST of the available space to reduce run time
14875         # else 60% of the available space if we are running SLOW tests
14876         if [ $SLOW == "no" ]; then
14877                 local space=$((1024 * 100 * OSTCOUNT))
14878         else
14879                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14880         fi
14881
14882         fallocate -l${space}k $DIR/$tfile ||
14883                 error "fallocate ${space}k $DIR/$tfile failed"
14884         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14885
14886         # get size immediately after fallocate. This should be correctly
14887         # updated
14888         local size=$(stat -c '%s' $DIR/$tfile)
14889         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14890
14891         # Sleep for a while for statfs to get updated. And not pull from cache.
14892         sleep 2
14893
14894         echo "df after fallocate:"
14895         $LFS df
14896
14897         (( size / 1024 == space )) || error "size $size != requested $space"
14898         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14899                 error "used $used < space $space"
14900
14901         rm $DIR/$tfile || error "rm failed"
14902         sync
14903         wait_delete_completed
14904
14905         echo "df after unlink:"
14906         $LFS df
14907 }
14908 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14909
14910 test_150f() {
14911         local size
14912         local blocks
14913         local want_size_before=20480 # in bytes
14914         local want_blocks_before=40 # 512 sized blocks
14915         local want_blocks_after=24  # 512 sized blocks
14916         local length=$(((want_blocks_before - want_blocks_after) * 512))
14917
14918         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14919                 skip "need at least 2.14.0 for fallocate punch"
14920
14921         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14922                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14923         fi
14924
14925         check_set_fallocate_or_skip
14926         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14927
14928         [[ "x$DOM" == "xyes" ]] &&
14929                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14930
14931         echo "Verify fallocate punch: Range within the file range"
14932         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14933                 error "dd failed for bs 4096 and count 5"
14934
14935         # Call fallocate with punch range which is within the file range
14936         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14937                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14938         # client must see changes immediately after fallocate
14939         size=$(stat -c '%s' $DIR/$tfile)
14940         blocks=$(stat -c '%b' $DIR/$tfile)
14941
14942         # Verify punch worked.
14943         (( blocks == want_blocks_after )) ||
14944                 error "punch failed: blocks $blocks != $want_blocks_after"
14945
14946         (( size == want_size_before )) ||
14947                 error "punch failed: size $size != $want_size_before"
14948
14949         # Verify there is hole in file
14950         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14951         # precomputed md5sum
14952         local expect="4a9a834a2db02452929c0a348273b4aa"
14953
14954         cksum=($(md5sum $DIR/$tfile))
14955         [[ "${cksum[0]}" == "$expect" ]] ||
14956                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14957
14958         # Start second sub-case for fallocate punch.
14959         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14960         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14961                 error "dd failed for bs 4096 and count 5"
14962
14963         # Punch range less than block size will have no change in block count
14964         want_blocks_after=40  # 512 sized blocks
14965
14966         # Punch overlaps two blocks and less than blocksize
14967         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14968                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14969         size=$(stat -c '%s' $DIR/$tfile)
14970         blocks=$(stat -c '%b' $DIR/$tfile)
14971
14972         # Verify punch worked.
14973         (( blocks == want_blocks_after )) ||
14974                 error "punch failed: blocks $blocks != $want_blocks_after"
14975
14976         (( size == want_size_before )) ||
14977                 error "punch failed: size $size != $want_size_before"
14978
14979         # Verify if range is really zero'ed out. We expect Zeros.
14980         # precomputed md5sum
14981         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14982         cksum=($(md5sum $DIR/$tfile))
14983         [[ "${cksum[0]}" == "$expect" ]] ||
14984                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14985 }
14986 run_test 150f "Verify fallocate punch functionality"
14987
14988 test_150g() {
14989         local space
14990         local size
14991         local blocks
14992         local blocks_after
14993         local size_after
14994         local BS=4096 # Block size in bytes
14995
14996         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14997                 skip "need at least 2.14.0 for fallocate punch"
14998
14999         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15000                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15001         fi
15002
15003         check_set_fallocate_or_skip
15004         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15005
15006         if [[ "x$DOM" == "xyes" ]]; then
15007                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15008                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15009         else
15010                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15011                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15012         fi
15013
15014         # Get 100MB per OST of the available space to reduce run time
15015         # else 60% of the available space if we are running SLOW tests
15016         if [ $SLOW == "no" ]; then
15017                 space=$((1024 * 100 * OSTCOUNT))
15018         else
15019                 # Find OST with Minimum Size
15020                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15021                         sort -un | head -1)
15022                 echo "min size OST: $space"
15023                 space=$(((space * 60)/100 * OSTCOUNT))
15024         fi
15025         # space in 1k units, round to 4k blocks
15026         local blkcount=$((space * 1024 / $BS))
15027
15028         echo "Verify fallocate punch: Very large Range"
15029         fallocate -l${space}k $DIR/$tfile ||
15030                 error "fallocate ${space}k $DIR/$tfile failed"
15031         # write 1M at the end, start and in the middle
15032         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15033                 error "dd failed: bs $BS count 256"
15034         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15035                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15036         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15037                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15038
15039         # Gather stats.
15040         size=$(stat -c '%s' $DIR/$tfile)
15041
15042         # gather punch length.
15043         local punch_size=$((size - (BS * 2)))
15044
15045         echo "punch_size = $punch_size"
15046         echo "size - punch_size: $((size - punch_size))"
15047         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15048
15049         # Call fallocate to punch all except 2 blocks. We leave the
15050         # first and the last block
15051         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15052         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15053                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15054
15055         size_after=$(stat -c '%s' $DIR/$tfile)
15056         blocks_after=$(stat -c '%b' $DIR/$tfile)
15057
15058         # Verify punch worked.
15059         # Size should be kept
15060         (( size == size_after )) ||
15061                 error "punch failed: size $size != $size_after"
15062
15063         # two 4k data blocks to remain plus possible 1 extra extent block
15064         (( blocks_after <= ((BS / 512) * 3) )) ||
15065                 error "too many blocks remains: $blocks_after"
15066
15067         # Verify that file has hole between the first and the last blocks
15068         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15069         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15070
15071         echo "Hole at [$hole_start, $hole_end)"
15072         (( hole_start == BS )) ||
15073                 error "no hole at offset $BS after punch"
15074
15075         (( hole_end == BS + punch_size )) ||
15076                 error "data at offset $hole_end < $((BS + punch_size))"
15077 }
15078 run_test 150g "Verify fallocate punch on large range"
15079
15080 #LU-2902 roc_hit was not able to read all values from lproc
15081 function roc_hit_init() {
15082         local list=$(comma_list $(osts_nodes))
15083         local dir=$DIR/$tdir-check
15084         local file=$dir/$tfile
15085         local BEFORE
15086         local AFTER
15087         local idx
15088
15089         test_mkdir $dir
15090         #use setstripe to do a write to every ost
15091         for i in $(seq 0 $((OSTCOUNT-1))); do
15092                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15093                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15094                 idx=$(printf %04x $i)
15095                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15096                         awk '$1 == "cache_access" {sum += $7}
15097                                 END { printf("%0.0f", sum) }')
15098
15099                 cancel_lru_locks osc
15100                 cat $file >/dev/null
15101
15102                 AFTER=$(get_osd_param $list *OST*$idx stats |
15103                         awk '$1 == "cache_access" {sum += $7}
15104                                 END { printf("%0.0f", sum) }')
15105
15106                 echo BEFORE:$BEFORE AFTER:$AFTER
15107                 if ! let "AFTER - BEFORE == 4"; then
15108                         rm -rf $dir
15109                         error "roc_hit is not safe to use"
15110                 fi
15111                 rm $file
15112         done
15113
15114         rm -rf $dir
15115 }
15116
15117 function roc_hit() {
15118         local list=$(comma_list $(osts_nodes))
15119         echo $(get_osd_param $list '' stats |
15120                 awk '$1 == "cache_hit" {sum += $7}
15121                         END { printf("%0.0f", sum) }')
15122 }
15123
15124 function set_cache() {
15125         local on=1
15126
15127         if [ "$2" == "off" ]; then
15128                 on=0;
15129         fi
15130         local list=$(comma_list $(osts_nodes))
15131         set_osd_param $list '' $1_cache_enable $on
15132
15133         cancel_lru_locks osc
15134 }
15135
15136 test_151() {
15137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15138         remote_ost_nodsh && skip "remote OST with nodsh"
15139
15140         local CPAGES=3
15141         local list=$(comma_list $(osts_nodes))
15142
15143         # check whether obdfilter is cache capable at all
15144         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15145                 skip "not cache-capable obdfilter"
15146         fi
15147
15148         # check cache is enabled on all obdfilters
15149         if get_osd_param $list '' read_cache_enable | grep 0; then
15150                 skip "oss cache is disabled"
15151         fi
15152
15153         set_osd_param $list '' writethrough_cache_enable 1
15154
15155         # check write cache is enabled on all obdfilters
15156         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15157                 skip "oss write cache is NOT enabled"
15158         fi
15159
15160         roc_hit_init
15161
15162         #define OBD_FAIL_OBD_NO_LRU  0x609
15163         do_nodes $list $LCTL set_param fail_loc=0x609
15164
15165         # pages should be in the case right after write
15166         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15167                 error "dd failed"
15168
15169         local BEFORE=$(roc_hit)
15170         cancel_lru_locks osc
15171         cat $DIR/$tfile >/dev/null
15172         local AFTER=$(roc_hit)
15173
15174         do_nodes $list $LCTL set_param fail_loc=0
15175
15176         if ! let "AFTER - BEFORE == CPAGES"; then
15177                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15178         fi
15179
15180         cancel_lru_locks osc
15181         # invalidates OST cache
15182         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15183         set_osd_param $list '' read_cache_enable 0
15184         cat $DIR/$tfile >/dev/null
15185
15186         # now data shouldn't be found in the cache
15187         BEFORE=$(roc_hit)
15188         cancel_lru_locks osc
15189         cat $DIR/$tfile >/dev/null
15190         AFTER=$(roc_hit)
15191         if let "AFTER - BEFORE != 0"; then
15192                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15193         fi
15194
15195         set_osd_param $list '' read_cache_enable 1
15196         rm -f $DIR/$tfile
15197 }
15198 run_test 151 "test cache on oss and controls ==============================="
15199
15200 test_152() {
15201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15202
15203         local TF="$TMP/$tfile"
15204
15205         # simulate ENOMEM during write
15206 #define OBD_FAIL_OST_NOMEM      0x226
15207         lctl set_param fail_loc=0x80000226
15208         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15209         cp $TF $DIR/$tfile
15210         sync || error "sync failed"
15211         lctl set_param fail_loc=0
15212
15213         # discard client's cache
15214         cancel_lru_locks osc
15215
15216         # simulate ENOMEM during read
15217         lctl set_param fail_loc=0x80000226
15218         cmp $TF $DIR/$tfile || error "cmp failed"
15219         lctl set_param fail_loc=0
15220
15221         rm -f $TF
15222 }
15223 run_test 152 "test read/write with enomem ============================"
15224
15225 test_153() {
15226         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15227 }
15228 run_test 153 "test if fdatasync does not crash ======================="
15229
15230 dot_lustre_fid_permission_check() {
15231         local fid=$1
15232         local ffid=$MOUNT/.lustre/fid/$fid
15233         local test_dir=$2
15234
15235         echo "stat fid $fid"
15236         stat $ffid > /dev/null || error "stat $ffid failed."
15237         echo "touch fid $fid"
15238         touch $ffid || error "touch $ffid failed."
15239         echo "write to fid $fid"
15240         cat /etc/hosts > $ffid || error "write $ffid failed."
15241         echo "read fid $fid"
15242         diff /etc/hosts $ffid || error "read $ffid failed."
15243         echo "append write to fid $fid"
15244         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15245         echo "rename fid $fid"
15246         mv $ffid $test_dir/$tfile.1 &&
15247                 error "rename $ffid to $tfile.1 should fail."
15248         touch $test_dir/$tfile.1
15249         mv $test_dir/$tfile.1 $ffid &&
15250                 error "rename $tfile.1 to $ffid should fail."
15251         rm -f $test_dir/$tfile.1
15252         echo "truncate fid $fid"
15253         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15254         echo "link fid $fid"
15255         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15256         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15257                 echo "setfacl fid $fid"
15258                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15259                 echo "getfacl fid $fid"
15260                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15261         fi
15262         echo "unlink fid $fid"
15263         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15264         echo "mknod fid $fid"
15265         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15266
15267         fid=[0xf00000400:0x1:0x0]
15268         ffid=$MOUNT/.lustre/fid/$fid
15269
15270         echo "stat non-exist fid $fid"
15271         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15272         echo "write to non-exist fid $fid"
15273         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15274         echo "link new fid $fid"
15275         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15276
15277         mkdir -p $test_dir/$tdir
15278         touch $test_dir/$tdir/$tfile
15279         fid=$($LFS path2fid $test_dir/$tdir)
15280         rc=$?
15281         [ $rc -ne 0 ] &&
15282                 error "error: could not get fid for $test_dir/$dir/$tfile."
15283
15284         ffid=$MOUNT/.lustre/fid/$fid
15285
15286         echo "ls $fid"
15287         ls $ffid > /dev/null || error "ls $ffid failed."
15288         echo "touch $fid/$tfile.1"
15289         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15290
15291         echo "touch $MOUNT/.lustre/fid/$tfile"
15292         touch $MOUNT/.lustre/fid/$tfile && \
15293                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15294
15295         echo "setxattr to $MOUNT/.lustre/fid"
15296         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15297
15298         echo "listxattr for $MOUNT/.lustre/fid"
15299         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15300
15301         echo "delxattr from $MOUNT/.lustre/fid"
15302         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15303
15304         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15305         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15306                 error "touch invalid fid should fail."
15307
15308         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15309         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15310                 error "touch non-normal fid should fail."
15311
15312         echo "rename $tdir to $MOUNT/.lustre/fid"
15313         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15314                 error "rename to $MOUNT/.lustre/fid should fail."
15315
15316         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15317         then            # LU-3547
15318                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15319                 local new_obf_mode=777
15320
15321                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15322                 chmod $new_obf_mode $DIR/.lustre/fid ||
15323                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15324
15325                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15326                 [ $obf_mode -eq $new_obf_mode ] ||
15327                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15328
15329                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15330                 chmod $old_obf_mode $DIR/.lustre/fid ||
15331                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15332         fi
15333
15334         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15335         fid=$($LFS path2fid $test_dir/$tfile-2)
15336
15337         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15338         then # LU-5424
15339                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15340                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15341                         error "create lov data thru .lustre failed"
15342         fi
15343         echo "cp /etc/passwd $test_dir/$tfile-2"
15344         cp /etc/passwd $test_dir/$tfile-2 ||
15345                 error "copy to $test_dir/$tfile-2 failed."
15346         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15347         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15348                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15349
15350         rm -rf $test_dir/tfile.lnk
15351         rm -rf $test_dir/$tfile-2
15352 }
15353
15354 test_154A() {
15355         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15356                 skip "Need MDS version at least 2.4.1"
15357
15358         local tf=$DIR/$tfile
15359         touch $tf
15360
15361         local fid=$($LFS path2fid $tf)
15362         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15363
15364         # check that we get the same pathname back
15365         local rootpath
15366         local found
15367         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15368                 echo "$rootpath $fid"
15369                 found=$($LFS fid2path $rootpath "$fid")
15370                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15371                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15372         done
15373
15374         # check wrong root path format
15375         rootpath=$MOUNT"_wrong"
15376         found=$($LFS fid2path $rootpath "$fid")
15377         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15378 }
15379 run_test 154A "lfs path2fid and fid2path basic checks"
15380
15381 test_154B() {
15382         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15383                 skip "Need MDS version at least 2.4.1"
15384
15385         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15386         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15387         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15388         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15389
15390         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15391         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15392
15393         # check that we get the same pathname
15394         echo "PFID: $PFID, name: $name"
15395         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15396         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15397         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15398                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15399
15400         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15401 }
15402 run_test 154B "verify the ll_decode_linkea tool"
15403
15404 test_154a() {
15405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15406         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15407         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15408                 skip "Need MDS version at least 2.2.51"
15409         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15410
15411         cp /etc/hosts $DIR/$tfile
15412
15413         fid=$($LFS path2fid $DIR/$tfile)
15414         rc=$?
15415         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15416
15417         dot_lustre_fid_permission_check "$fid" $DIR ||
15418                 error "dot lustre permission check $fid failed"
15419
15420         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15421
15422         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15423
15424         touch $MOUNT/.lustre/file &&
15425                 error "creation is not allowed under .lustre"
15426
15427         mkdir $MOUNT/.lustre/dir &&
15428                 error "mkdir is not allowed under .lustre"
15429
15430         rm -rf $DIR/$tfile
15431 }
15432 run_test 154a "Open-by-FID"
15433
15434 test_154b() {
15435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15436         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15437         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15438         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15439                 skip "Need MDS version at least 2.2.51"
15440
15441         local remote_dir=$DIR/$tdir/remote_dir
15442         local MDTIDX=1
15443         local rc=0
15444
15445         mkdir -p $DIR/$tdir
15446         $LFS mkdir -i $MDTIDX $remote_dir ||
15447                 error "create remote directory failed"
15448
15449         cp /etc/hosts $remote_dir/$tfile
15450
15451         fid=$($LFS path2fid $remote_dir/$tfile)
15452         rc=$?
15453         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15454
15455         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15456                 error "dot lustre permission check $fid failed"
15457         rm -rf $DIR/$tdir
15458 }
15459 run_test 154b "Open-by-FID for remote directory"
15460
15461 test_154c() {
15462         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15463                 skip "Need MDS version at least 2.4.1"
15464
15465         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15466         local FID1=$($LFS path2fid $DIR/$tfile.1)
15467         local FID2=$($LFS path2fid $DIR/$tfile.2)
15468         local FID3=$($LFS path2fid $DIR/$tfile.3)
15469
15470         local N=1
15471         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15472                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15473                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15474                 local want=FID$N
15475                 [ "$FID" = "${!want}" ] ||
15476                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15477                 N=$((N + 1))
15478         done
15479
15480         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15481         do
15482                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15483                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15484                 N=$((N + 1))
15485         done
15486 }
15487 run_test 154c "lfs path2fid and fid2path multiple arguments"
15488
15489 test_154d() {
15490         remote_mds_nodsh && skip "remote MDS with nodsh"
15491         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15492                 skip "Need MDS version at least 2.5.53"
15493
15494         if remote_mds; then
15495                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15496         else
15497                 nid="0@lo"
15498         fi
15499         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15500         local fd
15501         local cmd
15502
15503         rm -f $DIR/$tfile
15504         touch $DIR/$tfile
15505
15506         local fid=$($LFS path2fid $DIR/$tfile)
15507         # Open the file
15508         fd=$(free_fd)
15509         cmd="exec $fd<$DIR/$tfile"
15510         eval $cmd
15511         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15512         echo "$fid_list" | grep "$fid"
15513         rc=$?
15514
15515         cmd="exec $fd>/dev/null"
15516         eval $cmd
15517         if [ $rc -ne 0 ]; then
15518                 error "FID $fid not found in open files list $fid_list"
15519         fi
15520 }
15521 run_test 154d "Verify open file fid"
15522
15523 test_154e()
15524 {
15525         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15526                 skip "Need MDS version at least 2.6.50"
15527
15528         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15529                 error ".lustre returned by readdir"
15530         fi
15531 }
15532 run_test 154e ".lustre is not returned by readdir"
15533
15534 test_154f() {
15535         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15536
15537         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15538         mkdir_on_mdt0 $DIR/$tdir
15539         # test dirs inherit from its stripe
15540         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15541         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15542         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15543         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15544         touch $DIR/f
15545
15546         # get fid of parents
15547         local FID0=$($LFS path2fid $DIR/$tdir)
15548         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15549         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15550         local FID3=$($LFS path2fid $DIR)
15551
15552         # check that path2fid --parents returns expected <parent_fid>/name
15553         # 1) test for a directory (single parent)
15554         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15555         [ "$parent" == "$FID0/foo1" ] ||
15556                 error "expected parent: $FID0/foo1, got: $parent"
15557
15558         # 2) test for a file with nlink > 1 (multiple parents)
15559         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15560         echo "$parent" | grep -F "$FID1/$tfile" ||
15561                 error "$FID1/$tfile not returned in parent list"
15562         echo "$parent" | grep -F "$FID2/link" ||
15563                 error "$FID2/link not returned in parent list"
15564
15565         # 3) get parent by fid
15566         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15567         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15568         echo "$parent" | grep -F "$FID1/$tfile" ||
15569                 error "$FID1/$tfile not returned in parent list (by fid)"
15570         echo "$parent" | grep -F "$FID2/link" ||
15571                 error "$FID2/link not returned in parent list (by fid)"
15572
15573         # 4) test for entry in root directory
15574         parent=$($LFS path2fid --parents $DIR/f)
15575         echo "$parent" | grep -F "$FID3/f" ||
15576                 error "$FID3/f not returned in parent list"
15577
15578         # 5) test it on root directory
15579         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15580                 error "$MOUNT should not have parents"
15581
15582         # enable xattr caching and check that linkea is correctly updated
15583         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15584         save_lustre_params client "llite.*.xattr_cache" > $save
15585         lctl set_param llite.*.xattr_cache 1
15586
15587         # 6.1) linkea update on rename
15588         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15589
15590         # get parents by fid
15591         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15592         # foo1 should no longer be returned in parent list
15593         echo "$parent" | grep -F "$FID1" &&
15594                 error "$FID1 should no longer be in parent list"
15595         # the new path should appear
15596         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15597                 error "$FID2/$tfile.moved is not in parent list"
15598
15599         # 6.2) linkea update on unlink
15600         rm -f $DIR/$tdir/foo2/link
15601         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15602         # foo2/link should no longer be returned in parent list
15603         echo "$parent" | grep -F "$FID2/link" &&
15604                 error "$FID2/link should no longer be in parent list"
15605         true
15606
15607         rm -f $DIR/f
15608         restore_lustre_params < $save
15609         rm -f $save
15610 }
15611 run_test 154f "get parent fids by reading link ea"
15612
15613 test_154g()
15614 {
15615         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15616         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15617            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15618                 skip "Need MDS version at least 2.6.92"
15619
15620         mkdir_on_mdt0 $DIR/$tdir
15621         llapi_fid_test -d $DIR/$tdir
15622 }
15623 run_test 154g "various llapi FID tests"
15624
15625 test_155_small_load() {
15626     local temp=$TMP/$tfile
15627     local file=$DIR/$tfile
15628
15629     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15630         error "dd of=$temp bs=6096 count=1 failed"
15631     cp $temp $file
15632     cancel_lru_locks $OSC
15633     cmp $temp $file || error "$temp $file differ"
15634
15635     $TRUNCATE $temp 6000
15636     $TRUNCATE $file 6000
15637     cmp $temp $file || error "$temp $file differ (truncate1)"
15638
15639     echo "12345" >>$temp
15640     echo "12345" >>$file
15641     cmp $temp $file || error "$temp $file differ (append1)"
15642
15643     echo "12345" >>$temp
15644     echo "12345" >>$file
15645     cmp $temp $file || error "$temp $file differ (append2)"
15646
15647     rm -f $temp $file
15648     true
15649 }
15650
15651 test_155_big_load() {
15652         remote_ost_nodsh && skip "remote OST with nodsh"
15653
15654         local temp=$TMP/$tfile
15655         local file=$DIR/$tfile
15656
15657         free_min_max
15658         local cache_size=$(do_facet ost$((MAXI+1)) \
15659                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15660         local large_file_size=$((cache_size * 2))
15661
15662         echo "OSS cache size: $cache_size KB"
15663         echo "Large file size: $large_file_size KB"
15664
15665         [ $MAXV -le $large_file_size ] &&
15666                 skip_env "max available OST size needs > $large_file_size KB"
15667
15668         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15669
15670         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15671                 error "dd of=$temp bs=$large_file_size count=1k failed"
15672         cp $temp $file
15673         ls -lh $temp $file
15674         cancel_lru_locks osc
15675         cmp $temp $file || error "$temp $file differ"
15676
15677         rm -f $temp $file
15678         true
15679 }
15680
15681 save_writethrough() {
15682         local facets=$(get_facets OST)
15683
15684         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15685 }
15686
15687 test_155a() {
15688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15689
15690         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15691
15692         save_writethrough $p
15693
15694         set_cache read on
15695         set_cache writethrough on
15696         test_155_small_load
15697         restore_lustre_params < $p
15698         rm -f $p
15699 }
15700 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15701
15702 test_155b() {
15703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15704
15705         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15706
15707         save_writethrough $p
15708
15709         set_cache read on
15710         set_cache writethrough off
15711         test_155_small_load
15712         restore_lustre_params < $p
15713         rm -f $p
15714 }
15715 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15716
15717 test_155c() {
15718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15719
15720         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15721
15722         save_writethrough $p
15723
15724         set_cache read off
15725         set_cache writethrough on
15726         test_155_small_load
15727         restore_lustre_params < $p
15728         rm -f $p
15729 }
15730 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15731
15732 test_155d() {
15733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15734
15735         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15736
15737         save_writethrough $p
15738
15739         set_cache read off
15740         set_cache writethrough off
15741         test_155_small_load
15742         restore_lustre_params < $p
15743         rm -f $p
15744 }
15745 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15746
15747 test_155e() {
15748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15749
15750         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15751
15752         save_writethrough $p
15753
15754         set_cache read on
15755         set_cache writethrough on
15756         test_155_big_load
15757         restore_lustre_params < $p
15758         rm -f $p
15759 }
15760 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15761
15762 test_155f() {
15763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15764
15765         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15766
15767         save_writethrough $p
15768
15769         set_cache read on
15770         set_cache writethrough off
15771         test_155_big_load
15772         restore_lustre_params < $p
15773         rm -f $p
15774 }
15775 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15776
15777 test_155g() {
15778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15779
15780         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15781
15782         save_writethrough $p
15783
15784         set_cache read off
15785         set_cache writethrough on
15786         test_155_big_load
15787         restore_lustre_params < $p
15788         rm -f $p
15789 }
15790 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15791
15792 test_155h() {
15793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15794
15795         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15796
15797         save_writethrough $p
15798
15799         set_cache read off
15800         set_cache writethrough off
15801         test_155_big_load
15802         restore_lustre_params < $p
15803         rm -f $p
15804 }
15805 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15806
15807 test_156() {
15808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15809         remote_ost_nodsh && skip "remote OST with nodsh"
15810         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15811                 skip "stats not implemented on old servers"
15812         [ "$ost1_FSTYPE" = "zfs" ] &&
15813                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15814
15815         local CPAGES=3
15816         local BEFORE
15817         local AFTER
15818         local file="$DIR/$tfile"
15819         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15820
15821         save_writethrough $p
15822         roc_hit_init
15823
15824         log "Turn on read and write cache"
15825         set_cache read on
15826         set_cache writethrough on
15827
15828         log "Write data and read it back."
15829         log "Read should be satisfied from the cache."
15830         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15831         BEFORE=$(roc_hit)
15832         cancel_lru_locks osc
15833         cat $file >/dev/null
15834         AFTER=$(roc_hit)
15835         if ! let "AFTER - BEFORE == CPAGES"; then
15836                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15837         else
15838                 log "cache hits: before: $BEFORE, after: $AFTER"
15839         fi
15840
15841         log "Read again; it should be satisfied from the cache."
15842         BEFORE=$AFTER
15843         cancel_lru_locks osc
15844         cat $file >/dev/null
15845         AFTER=$(roc_hit)
15846         if ! let "AFTER - BEFORE == CPAGES"; then
15847                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15848         else
15849                 log "cache hits:: before: $BEFORE, after: $AFTER"
15850         fi
15851
15852         log "Turn off the read cache and turn on the write cache"
15853         set_cache read off
15854         set_cache writethrough on
15855
15856         log "Read again; it should be satisfied from the cache."
15857         BEFORE=$(roc_hit)
15858         cancel_lru_locks osc
15859         cat $file >/dev/null
15860         AFTER=$(roc_hit)
15861         if ! let "AFTER - BEFORE == CPAGES"; then
15862                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15863         else
15864                 log "cache hits:: before: $BEFORE, after: $AFTER"
15865         fi
15866
15867         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15868                 # > 2.12.56 uses pagecache if cached
15869                 log "Read again; it should not be satisfied from the cache."
15870                 BEFORE=$AFTER
15871                 cancel_lru_locks osc
15872                 cat $file >/dev/null
15873                 AFTER=$(roc_hit)
15874                 if ! let "AFTER - BEFORE == 0"; then
15875                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15876                 else
15877                         log "cache hits:: before: $BEFORE, after: $AFTER"
15878                 fi
15879         fi
15880
15881         log "Write data and read it back."
15882         log "Read should be satisfied from the cache."
15883         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15884         BEFORE=$(roc_hit)
15885         cancel_lru_locks osc
15886         cat $file >/dev/null
15887         AFTER=$(roc_hit)
15888         if ! let "AFTER - BEFORE == CPAGES"; then
15889                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15890         else
15891                 log "cache hits:: before: $BEFORE, after: $AFTER"
15892         fi
15893
15894         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15895                 # > 2.12.56 uses pagecache if cached
15896                 log "Read again; it should not be satisfied from the cache."
15897                 BEFORE=$AFTER
15898                 cancel_lru_locks osc
15899                 cat $file >/dev/null
15900                 AFTER=$(roc_hit)
15901                 if ! let "AFTER - BEFORE == 0"; then
15902                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15903                 else
15904                         log "cache hits:: before: $BEFORE, after: $AFTER"
15905                 fi
15906         fi
15907
15908         log "Turn off read and write cache"
15909         set_cache read off
15910         set_cache writethrough off
15911
15912         log "Write data and read it back"
15913         log "It should not be satisfied from the cache."
15914         rm -f $file
15915         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15916         cancel_lru_locks osc
15917         BEFORE=$(roc_hit)
15918         cat $file >/dev/null
15919         AFTER=$(roc_hit)
15920         if ! let "AFTER - BEFORE == 0"; then
15921                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15922         else
15923                 log "cache hits:: before: $BEFORE, after: $AFTER"
15924         fi
15925
15926         log "Turn on the read cache and turn off the write cache"
15927         set_cache read on
15928         set_cache writethrough off
15929
15930         log "Write data and read it back"
15931         log "It should not be satisfied from the cache."
15932         rm -f $file
15933         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15934         BEFORE=$(roc_hit)
15935         cancel_lru_locks osc
15936         cat $file >/dev/null
15937         AFTER=$(roc_hit)
15938         if ! let "AFTER - BEFORE == 0"; then
15939                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15940         else
15941                 log "cache hits:: before: $BEFORE, after: $AFTER"
15942         fi
15943
15944         log "Read again; it should be satisfied from the cache."
15945         BEFORE=$(roc_hit)
15946         cancel_lru_locks osc
15947         cat $file >/dev/null
15948         AFTER=$(roc_hit)
15949         if ! let "AFTER - BEFORE == CPAGES"; then
15950                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15951         else
15952                 log "cache hits:: before: $BEFORE, after: $AFTER"
15953         fi
15954
15955         restore_lustre_params < $p
15956         rm -f $p $file
15957 }
15958 run_test 156 "Verification of tunables"
15959
15960 test_160a() {
15961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15962         remote_mds_nodsh && skip "remote MDS with nodsh"
15963         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15964                 skip "Need MDS version at least 2.2.0"
15965
15966         changelog_register || error "changelog_register failed"
15967         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15968         changelog_users $SINGLEMDS | grep -q $cl_user ||
15969                 error "User $cl_user not found in changelog_users"
15970
15971         mkdir_on_mdt0 $DIR/$tdir
15972
15973         # change something
15974         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15975         changelog_clear 0 || error "changelog_clear failed"
15976         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15977         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15978         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15979         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15980         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15981         rm $DIR/$tdir/pics/desktop.jpg
15982
15983         echo "verifying changelog mask"
15984         changelog_chmask "-MKDIR"
15985         changelog_chmask "-CLOSE"
15986
15987         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15988         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15989
15990         changelog_chmask "+MKDIR"
15991         changelog_chmask "+CLOSE"
15992
15993         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15994         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15995
15996         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15997         CLOSES=$(changelog_dump | grep -c "CLOSE")
15998         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15999         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16000
16001         # verify contents
16002         echo "verifying target fid"
16003         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16004         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16005         [ "$fidc" == "$fidf" ] ||
16006                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16007         echo "verifying parent fid"
16008         # The FID returned from the Changelog may be the directory shard on
16009         # a different MDT, and not the FID returned by path2fid on the parent.
16010         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16011         # since this is what will matter when recreating this file in the tree.
16012         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16013         local pathp=$($LFS fid2path $MOUNT "$fidp")
16014         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16015                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16016
16017         echo "getting records for $cl_user"
16018         changelog_users $SINGLEMDS
16019         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16020         local nclr=3
16021         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16022                 error "changelog_clear failed"
16023         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16024         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16025         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16026                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16027
16028         local min0_rec=$(changelog_users $SINGLEMDS |
16029                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16030         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16031                           awk '{ print $1; exit; }')
16032
16033         changelog_dump | tail -n 5
16034         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16035         [ $first_rec == $((min0_rec + 1)) ] ||
16036                 error "first index should be $min0_rec + 1 not $first_rec"
16037
16038         # LU-3446 changelog index reset on MDT restart
16039         local cur_rec1=$(changelog_users $SINGLEMDS |
16040                          awk '/^current.index:/ { print $NF }')
16041         changelog_clear 0 ||
16042                 error "clear all changelog records for $cl_user failed"
16043         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16044         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16045                 error "Fail to start $SINGLEMDS"
16046         local cur_rec2=$(changelog_users $SINGLEMDS |
16047                          awk '/^current.index:/ { print $NF }')
16048         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16049         [ $cur_rec1 == $cur_rec2 ] ||
16050                 error "current index should be $cur_rec1 not $cur_rec2"
16051
16052         echo "verifying users from this test are deregistered"
16053         changelog_deregister || error "changelog_deregister failed"
16054         changelog_users $SINGLEMDS | grep -q $cl_user &&
16055                 error "User '$cl_user' still in changelog_users"
16056
16057         # lctl get_param -n mdd.*.changelog_users
16058         # current_index: 144
16059         # ID    index (idle seconds)
16060         # cl3   144   (2) mask=<list>
16061         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16062                 # this is the normal case where all users were deregistered
16063                 # make sure no new records are added when no users are present
16064                 local last_rec1=$(changelog_users $SINGLEMDS |
16065                                   awk '/^current.index:/ { print $NF }')
16066                 touch $DIR/$tdir/chloe
16067                 local last_rec2=$(changelog_users $SINGLEMDS |
16068                                   awk '/^current.index:/ { print $NF }')
16069                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16070                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16071         else
16072                 # any changelog users must be leftovers from a previous test
16073                 changelog_users $SINGLEMDS
16074                 echo "other changelog users; can't verify off"
16075         fi
16076 }
16077 run_test 160a "changelog sanity"
16078
16079 test_160b() { # LU-3587
16080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16081         remote_mds_nodsh && skip "remote MDS with nodsh"
16082         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16083                 skip "Need MDS version at least 2.2.0"
16084
16085         changelog_register || error "changelog_register failed"
16086         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16087         changelog_users $SINGLEMDS | grep -q $cl_user ||
16088                 error "User '$cl_user' not found in changelog_users"
16089
16090         local longname1=$(str_repeat a 255)
16091         local longname2=$(str_repeat b 255)
16092
16093         cd $DIR
16094         echo "creating very long named file"
16095         touch $longname1 || error "create of '$longname1' failed"
16096         echo "renaming very long named file"
16097         mv $longname1 $longname2
16098
16099         changelog_dump | grep RENME | tail -n 5
16100         rm -f $longname2
16101 }
16102 run_test 160b "Verify that very long rename doesn't crash in changelog"
16103
16104 test_160c() {
16105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16106         remote_mds_nodsh && skip "remote MDS with nodsh"
16107
16108         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16109                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16110                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16111                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16112
16113         local rc=0
16114
16115         # Registration step
16116         changelog_register || error "changelog_register failed"
16117
16118         rm -rf $DIR/$tdir
16119         mkdir -p $DIR/$tdir
16120         $MCREATE $DIR/$tdir/foo_160c
16121         changelog_chmask "-TRUNC"
16122         $TRUNCATE $DIR/$tdir/foo_160c 200
16123         changelog_chmask "+TRUNC"
16124         $TRUNCATE $DIR/$tdir/foo_160c 199
16125         changelog_dump | tail -n 5
16126         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16127         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16128 }
16129 run_test 160c "verify that changelog log catch the truncate event"
16130
16131 test_160d() {
16132         remote_mds_nodsh && skip "remote MDS with nodsh"
16133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16135         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16136                 skip "Need MDS version at least 2.7.60"
16137
16138         # Registration step
16139         changelog_register || error "changelog_register failed"
16140
16141         mkdir -p $DIR/$tdir/migrate_dir
16142         changelog_clear 0 || error "changelog_clear failed"
16143
16144         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16145         changelog_dump | tail -n 5
16146         local migrates=$(changelog_dump | grep -c "MIGRT")
16147         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16148 }
16149 run_test 160d "verify that changelog log catch the migrate event"
16150
16151 test_160e() {
16152         remote_mds_nodsh && skip "remote MDS with nodsh"
16153
16154         # Create a user
16155         changelog_register || error "changelog_register failed"
16156
16157         local MDT0=$(facet_svc $SINGLEMDS)
16158         local rc
16159
16160         # No user (expect fail)
16161         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16162         rc=$?
16163         if [ $rc -eq 0 ]; then
16164                 error "Should fail without user"
16165         elif [ $rc -ne 4 ]; then
16166                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16167         fi
16168
16169         # Delete a future user (expect fail)
16170         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16171         rc=$?
16172         if [ $rc -eq 0 ]; then
16173                 error "Deleted non-existant user cl77"
16174         elif [ $rc -ne 2 ]; then
16175                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16176         fi
16177
16178         # Clear to a bad index (1 billion should be safe)
16179         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16180         rc=$?
16181
16182         if [ $rc -eq 0 ]; then
16183                 error "Successfully cleared to invalid CL index"
16184         elif [ $rc -ne 22 ]; then
16185                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16186         fi
16187 }
16188 run_test 160e "changelog negative testing (should return errors)"
16189
16190 test_160f() {
16191         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16192         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16193                 skip "Need MDS version at least 2.10.56"
16194
16195         local mdts=$(comma_list $(mdts_nodes))
16196
16197         # Create a user
16198         changelog_register || error "first changelog_register failed"
16199         changelog_register || error "second changelog_register failed"
16200         local cl_users
16201         declare -A cl_user1
16202         declare -A cl_user2
16203         local user_rec1
16204         local user_rec2
16205         local i
16206
16207         # generate some changelog records to accumulate on each MDT
16208         # use all_char because created files should be evenly distributed
16209         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16210                 error "test_mkdir $tdir failed"
16211         log "$(date +%s): creating first files"
16212         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16213                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16214                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16215         done
16216
16217         # check changelogs have been generated
16218         local start=$SECONDS
16219         local idle_time=$((MDSCOUNT * 5 + 5))
16220         local nbcl=$(changelog_dump | wc -l)
16221         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16222
16223         for param in "changelog_max_idle_time=$idle_time" \
16224                      "changelog_gc=1" \
16225                      "changelog_min_gc_interval=2" \
16226                      "changelog_min_free_cat_entries=3"; do
16227                 local MDT0=$(facet_svc $SINGLEMDS)
16228                 local var="${param%=*}"
16229                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16230
16231                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16232                 do_nodes $mdts $LCTL set_param mdd.*.$param
16233         done
16234
16235         # force cl_user2 to be idle (1st part), but also cancel the
16236         # cl_user1 records so that it is not evicted later in the test.
16237         local sleep1=$((idle_time / 2))
16238         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16239         sleep $sleep1
16240
16241         # simulate changelog catalog almost full
16242         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16243         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16244
16245         for i in $(seq $MDSCOUNT); do
16246                 cl_users=(${CL_USERS[mds$i]})
16247                 cl_user1[mds$i]="${cl_users[0]}"
16248                 cl_user2[mds$i]="${cl_users[1]}"
16249
16250                 [ -n "${cl_user1[mds$i]}" ] ||
16251                         error "mds$i: no user registered"
16252                 [ -n "${cl_user2[mds$i]}" ] ||
16253                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16254
16255                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16256                 [ -n "$user_rec1" ] ||
16257                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16258                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16259                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16260                 [ -n "$user_rec2" ] ||
16261                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16262                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16263                      "$user_rec1 + 2 == $user_rec2"
16264                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16265                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16266                               "$user_rec1 + 2, but is $user_rec2"
16267                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16268                 [ -n "$user_rec2" ] ||
16269                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16270                 [ $user_rec1 == $user_rec2 ] ||
16271                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16272                               "$user_rec1, but is $user_rec2"
16273         done
16274
16275         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16276         local sleep2=$((idle_time - (SECONDS - start) + 1))
16277         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16278         sleep $sleep2
16279
16280         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16281         # cl_user1 should be OK because it recently processed records.
16282         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16283         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16284                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16285                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16286         done
16287
16288         # ensure gc thread is done
16289         for i in $(mdts_nodes); do
16290                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16291                         error "$i: GC-thread not done"
16292         done
16293
16294         local first_rec
16295         for (( i = 1; i <= MDSCOUNT; i++ )); do
16296                 # check cl_user1 still registered
16297                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16298                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16299                 # check cl_user2 unregistered
16300                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16301                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16302
16303                 # check changelogs are present and starting at $user_rec1 + 1
16304                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16305                 [ -n "$user_rec1" ] ||
16306                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16307                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16308                             awk '{ print $1; exit; }')
16309
16310                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16311                 [ $((user_rec1 + 1)) == $first_rec ] ||
16312                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16313         done
16314 }
16315 run_test 160f "changelog garbage collect (timestamped users)"
16316
16317 test_160g() {
16318         remote_mds_nodsh && skip "remote MDS with nodsh"
16319         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16320                 skip "Need MDS version at least 2.14.55"
16321
16322         local mdts=$(comma_list $(mdts_nodes))
16323
16324         # Create a user
16325         changelog_register || error "first changelog_register failed"
16326         changelog_register || error "second changelog_register failed"
16327         local cl_users
16328         declare -A cl_user1
16329         declare -A cl_user2
16330         local user_rec1
16331         local user_rec2
16332         local i
16333
16334         # generate some changelog records to accumulate on each MDT
16335         # use all_char because created files should be evenly distributed
16336         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16337                 error "test_mkdir $tdir failed"
16338         for ((i = 0; i < MDSCOUNT; i++)); do
16339                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16340                         error "create $DIR/$tdir/d$i.1 failed"
16341         done
16342
16343         # check changelogs have been generated
16344         local nbcl=$(changelog_dump | wc -l)
16345         (( $nbcl > 0 )) || error "no changelogs found"
16346
16347         # reduce the max_idle_indexes value to make sure we exceed it
16348         for param in "changelog_max_idle_indexes=2" \
16349                      "changelog_gc=1" \
16350                      "changelog_min_gc_interval=2"; do
16351                 local MDT0=$(facet_svc $SINGLEMDS)
16352                 local var="${param%=*}"
16353                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16354
16355                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16356                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16357                         error "unable to set mdd.*.$param"
16358         done
16359
16360         local start=$SECONDS
16361         for i in $(seq $MDSCOUNT); do
16362                 cl_users=(${CL_USERS[mds$i]})
16363                 cl_user1[mds$i]="${cl_users[0]}"
16364                 cl_user2[mds$i]="${cl_users[1]}"
16365
16366                 [ -n "${cl_user1[mds$i]}" ] ||
16367                         error "mds$i: user1 is not registered"
16368                 [ -n "${cl_user2[mds$i]}" ] ||
16369                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16370
16371                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16372                 [ -n "$user_rec1" ] ||
16373                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16374                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16375                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16376                 [ -n "$user_rec2" ] ||
16377                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16378                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16379                      "$user_rec1 + 2 == $user_rec2"
16380                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16381                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16382                               "expected $user_rec1 + 2, but is $user_rec2"
16383                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16384                 [ -n "$user_rec2" ] ||
16385                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16386                 [ $user_rec1 == $user_rec2 ] ||
16387                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16388                               "expected $user_rec1, but is $user_rec2"
16389         done
16390
16391         # ensure we are past the previous changelog_min_gc_interval set above
16392         local sleep2=$((start + 2 - SECONDS))
16393         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16394         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16395         # cl_user1 should be OK because it recently processed records.
16396         for ((i = 0; i < MDSCOUNT; i++)); do
16397                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16398                         error "create $DIR/$tdir/d$i.3 failed"
16399         done
16400
16401         # ensure gc thread is done
16402         for i in $(mdts_nodes); do
16403                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16404                         error "$i: GC-thread not done"
16405         done
16406
16407         local first_rec
16408         for (( i = 1; i <= MDSCOUNT; i++ )); do
16409                 # check cl_user1 still registered
16410                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16411                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16412                 # check cl_user2 unregistered
16413                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16414                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16415
16416                 # check changelogs are present and starting at $user_rec1 + 1
16417                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16418                 [ -n "$user_rec1" ] ||
16419                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16420                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16421                             awk '{ print $1; exit; }')
16422
16423                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16424                 [ $((user_rec1 + 1)) == $first_rec ] ||
16425                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16426         done
16427 }
16428 run_test 160g "changelog garbage collect on idle records"
16429
16430 test_160h() {
16431         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16432         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16433                 skip "Need MDS version at least 2.10.56"
16434
16435         local mdts=$(comma_list $(mdts_nodes))
16436
16437         # Create a user
16438         changelog_register || error "first changelog_register failed"
16439         changelog_register || error "second changelog_register failed"
16440         local cl_users
16441         declare -A cl_user1
16442         declare -A cl_user2
16443         local user_rec1
16444         local user_rec2
16445         local i
16446
16447         # generate some changelog records to accumulate on each MDT
16448         # use all_char because created files should be evenly distributed
16449         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16450                 error "test_mkdir $tdir failed"
16451         for ((i = 0; i < MDSCOUNT; i++)); do
16452                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16453                         error "create $DIR/$tdir/d$i.1 failed"
16454         done
16455
16456         # check changelogs have been generated
16457         local nbcl=$(changelog_dump | wc -l)
16458         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16459
16460         for param in "changelog_max_idle_time=10" \
16461                      "changelog_gc=1" \
16462                      "changelog_min_gc_interval=2"; do
16463                 local MDT0=$(facet_svc $SINGLEMDS)
16464                 local var="${param%=*}"
16465                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16466
16467                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16468                 do_nodes $mdts $LCTL set_param mdd.*.$param
16469         done
16470
16471         # force cl_user2 to be idle (1st part)
16472         sleep 9
16473
16474         for i in $(seq $MDSCOUNT); do
16475                 cl_users=(${CL_USERS[mds$i]})
16476                 cl_user1[mds$i]="${cl_users[0]}"
16477                 cl_user2[mds$i]="${cl_users[1]}"
16478
16479                 [ -n "${cl_user1[mds$i]}" ] ||
16480                         error "mds$i: no user registered"
16481                 [ -n "${cl_user2[mds$i]}" ] ||
16482                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16483
16484                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16485                 [ -n "$user_rec1" ] ||
16486                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16487                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16488                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16489                 [ -n "$user_rec2" ] ||
16490                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16491                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16492                      "$user_rec1 + 2 == $user_rec2"
16493                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16494                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16495                               "$user_rec1 + 2, but is $user_rec2"
16496                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16497                 [ -n "$user_rec2" ] ||
16498                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16499                 [ $user_rec1 == $user_rec2 ] ||
16500                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16501                               "$user_rec1, but is $user_rec2"
16502         done
16503
16504         # force cl_user2 to be idle (2nd part) and to reach
16505         # changelog_max_idle_time
16506         sleep 2
16507
16508         # force each GC-thread start and block then
16509         # one per MDT/MDD, set fail_val accordingly
16510         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16511         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16512
16513         # generate more changelogs to trigger fail_loc
16514         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16515                 error "create $DIR/$tdir/${tfile}bis failed"
16516
16517         # stop MDT to stop GC-thread, should be done in back-ground as it will
16518         # block waiting for the thread to be released and exit
16519         declare -A stop_pids
16520         for i in $(seq $MDSCOUNT); do
16521                 stop mds$i &
16522                 stop_pids[mds$i]=$!
16523         done
16524
16525         for i in $(mdts_nodes); do
16526                 local facet
16527                 local nb=0
16528                 local facets=$(facets_up_on_host $i)
16529
16530                 for facet in ${facets//,/ }; do
16531                         if [[ $facet == mds* ]]; then
16532                                 nb=$((nb + 1))
16533                         fi
16534                 done
16535                 # ensure each MDS's gc threads are still present and all in "R"
16536                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16537                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16538                         error "$i: expected $nb GC-thread"
16539                 wait_update $i \
16540                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16541                         "R" 20 ||
16542                         error "$i: GC-thread not found in R-state"
16543                 # check umounts of each MDT on MDS have reached kthread_stop()
16544                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16545                         error "$i: expected $nb umount"
16546                 wait_update $i \
16547                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16548                         error "$i: umount not found in D-state"
16549         done
16550
16551         # release all GC-threads
16552         do_nodes $mdts $LCTL set_param fail_loc=0
16553
16554         # wait for MDT stop to complete
16555         for i in $(seq $MDSCOUNT); do
16556                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16557         done
16558
16559         # XXX
16560         # may try to check if any orphan changelog records are present
16561         # via ldiskfs/zfs and llog_reader...
16562
16563         # re-start/mount MDTs
16564         for i in $(seq $MDSCOUNT); do
16565                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16566                         error "Fail to start mds$i"
16567         done
16568
16569         local first_rec
16570         for i in $(seq $MDSCOUNT); do
16571                 # check cl_user1 still registered
16572                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16573                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16574                 # check cl_user2 unregistered
16575                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16576                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16577
16578                 # check changelogs are present and starting at $user_rec1 + 1
16579                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16580                 [ -n "$user_rec1" ] ||
16581                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16582                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16583                             awk '{ print $1; exit; }')
16584
16585                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16586                 [ $((user_rec1 + 1)) == $first_rec ] ||
16587                         error "mds$i: first index should be $user_rec1 + 1, " \
16588                               "but is $first_rec"
16589         done
16590 }
16591 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16592               "during mount"
16593
16594 test_160i() {
16595
16596         local mdts=$(comma_list $(mdts_nodes))
16597
16598         changelog_register || error "first changelog_register failed"
16599
16600         # generate some changelog records to accumulate on each MDT
16601         # use all_char because created files should be evenly distributed
16602         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16603                 error "test_mkdir $tdir failed"
16604         for ((i = 0; i < MDSCOUNT; i++)); do
16605                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16606                         error "create $DIR/$tdir/d$i.1 failed"
16607         done
16608
16609         # check changelogs have been generated
16610         local nbcl=$(changelog_dump | wc -l)
16611         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16612
16613         # simulate race between register and unregister
16614         # XXX as fail_loc is set per-MDS, with DNE configs the race
16615         # simulation will only occur for one MDT per MDS and for the
16616         # others the normal race scenario will take place
16617         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16618         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16619         do_nodes $mdts $LCTL set_param fail_val=1
16620
16621         # unregister 1st user
16622         changelog_deregister &
16623         local pid1=$!
16624         # wait some time for deregister work to reach race rdv
16625         sleep 2
16626         # register 2nd user
16627         changelog_register || error "2nd user register failed"
16628
16629         wait $pid1 || error "1st user deregister failed"
16630
16631         local i
16632         local last_rec
16633         declare -A LAST_REC
16634         for i in $(seq $MDSCOUNT); do
16635                 if changelog_users mds$i | grep "^cl"; then
16636                         # make sure new records are added with one user present
16637                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16638                                           awk '/^current.index:/ { print $NF }')
16639                 else
16640                         error "mds$i has no user registered"
16641                 fi
16642         done
16643
16644         # generate more changelog records to accumulate on each MDT
16645         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16646                 error "create $DIR/$tdir/${tfile}bis failed"
16647
16648         for i in $(seq $MDSCOUNT); do
16649                 last_rec=$(changelog_users $SINGLEMDS |
16650                            awk '/^current.index:/ { print $NF }')
16651                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16652                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16653                         error "changelogs are off on mds$i"
16654         done
16655 }
16656 run_test 160i "changelog user register/unregister race"
16657
16658 test_160j() {
16659         remote_mds_nodsh && skip "remote MDS with nodsh"
16660         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16661                 skip "Need MDS version at least 2.12.56"
16662
16663         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16664         stack_trap "umount $MOUNT2" EXIT
16665
16666         changelog_register || error "first changelog_register failed"
16667         stack_trap "changelog_deregister" EXIT
16668
16669         # generate some changelog
16670         # use all_char because created files should be evenly distributed
16671         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16672                 error "mkdir $tdir failed"
16673         for ((i = 0; i < MDSCOUNT; i++)); do
16674                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16675                         error "create $DIR/$tdir/d$i.1 failed"
16676         done
16677
16678         # open the changelog device
16679         exec 3>/dev/changelog-$FSNAME-MDT0000
16680         stack_trap "exec 3>&-" EXIT
16681         exec 4</dev/changelog-$FSNAME-MDT0000
16682         stack_trap "exec 4<&-" EXIT
16683
16684         # umount the first lustre mount
16685         umount $MOUNT
16686         stack_trap "mount_client $MOUNT" EXIT
16687
16688         # read changelog, which may or may not fail, but should not crash
16689         cat <&4 >/dev/null
16690
16691         # clear changelog
16692         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16693         changelog_users $SINGLEMDS | grep -q $cl_user ||
16694                 error "User $cl_user not found in changelog_users"
16695
16696         printf 'clear:'$cl_user':0' >&3
16697 }
16698 run_test 160j "client can be umounted while its chanangelog is being used"
16699
16700 test_160k() {
16701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16702         remote_mds_nodsh && skip "remote MDS with nodsh"
16703
16704         mkdir -p $DIR/$tdir/1/1
16705
16706         changelog_register || error "changelog_register failed"
16707         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16708
16709         changelog_users $SINGLEMDS | grep -q $cl_user ||
16710                 error "User '$cl_user' not found in changelog_users"
16711 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16712         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16713         rmdir $DIR/$tdir/1/1 & sleep 1
16714         mkdir $DIR/$tdir/2
16715         touch $DIR/$tdir/2/2
16716         rm -rf $DIR/$tdir/2
16717
16718         wait
16719         sleep 4
16720
16721         changelog_dump | grep rmdir || error "rmdir not recorded"
16722 }
16723 run_test 160k "Verify that changelog records are not lost"
16724
16725 # Verifies that a file passed as a parameter has recently had an operation
16726 # performed on it that has generated an MTIME changelog which contains the
16727 # correct parent FID. As files might reside on a different MDT from the
16728 # parent directory in DNE configurations, the FIDs are translated to paths
16729 # before being compared, which should be identical
16730 compare_mtime_changelog() {
16731         local file="${1}"
16732         local mdtidx
16733         local mtime
16734         local cl_fid
16735         local pdir
16736         local dir
16737
16738         mdtidx=$($LFS getstripe --mdt-index $file)
16739         mdtidx=$(printf "%04x" $mdtidx)
16740
16741         # Obtain the parent FID from the MTIME changelog
16742         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16743         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16744
16745         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16746         [ -z "$cl_fid" ] && error "parent FID not present"
16747
16748         # Verify that the path for the parent FID is the same as the path for
16749         # the test directory
16750         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16751
16752         dir=$(dirname $1)
16753
16754         [[ "${pdir%/}" == "$dir" ]] ||
16755                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16756 }
16757
16758 test_160l() {
16759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16760
16761         remote_mds_nodsh && skip "remote MDS with nodsh"
16762         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16763                 skip "Need MDS version at least 2.13.55"
16764
16765         local cl_user
16766
16767         changelog_register || error "changelog_register failed"
16768         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16769
16770         changelog_users $SINGLEMDS | grep -q $cl_user ||
16771                 error "User '$cl_user' not found in changelog_users"
16772
16773         # Clear some types so that MTIME changelogs are generated
16774         changelog_chmask "-CREAT"
16775         changelog_chmask "-CLOSE"
16776
16777         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16778
16779         # Test CL_MTIME during setattr
16780         touch $DIR/$tdir/$tfile
16781         compare_mtime_changelog $DIR/$tdir/$tfile
16782
16783         # Test CL_MTIME during close
16784         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16785         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16786 }
16787 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16788
16789 test_160m() {
16790         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16791         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16792                 skip "Need MDS version at least 2.14.51"
16793         local cl_users
16794         local cl_user1
16795         local cl_user2
16796         local pid1
16797
16798         # Create a user
16799         changelog_register || error "first changelog_register failed"
16800         changelog_register || error "second changelog_register failed"
16801
16802         cl_users=(${CL_USERS[mds1]})
16803         cl_user1="${cl_users[0]}"
16804         cl_user2="${cl_users[1]}"
16805         # generate some changelog records to accumulate on MDT0
16806         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16807         createmany -m $DIR/$tdir/$tfile 50 ||
16808                 error "create $DIR/$tdir/$tfile failed"
16809         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16810         rm -f $DIR/$tdir
16811
16812         # check changelogs have been generated
16813         local nbcl=$(changelog_dump | wc -l)
16814         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16815
16816 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16817         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16818
16819         __changelog_clear mds1 $cl_user1 +10
16820         __changelog_clear mds1 $cl_user2 0 &
16821         pid1=$!
16822         sleep 2
16823         __changelog_clear mds1 $cl_user1 0 ||
16824                 error "fail to cancel record for $cl_user1"
16825         wait $pid1
16826         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16827 }
16828 run_test 160m "Changelog clear race"
16829
16830 test_160n() {
16831         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16832         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16833                 skip "Need MDS version at least 2.14.51"
16834         local cl_users
16835         local cl_user1
16836         local cl_user2
16837         local pid1
16838         local first_rec
16839         local last_rec=0
16840
16841         # Create a user
16842         changelog_register || error "first changelog_register failed"
16843
16844         cl_users=(${CL_USERS[mds1]})
16845         cl_user1="${cl_users[0]}"
16846
16847         # generate some changelog records to accumulate on MDT0
16848         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16849         first_rec=$(changelog_users $SINGLEMDS |
16850                         awk '/^current.index:/ { print $NF }')
16851         while (( last_rec < (( first_rec + 65000)) )); do
16852                 createmany -m $DIR/$tdir/$tfile 10000 ||
16853                         error "create $DIR/$tdir/$tfile failed"
16854
16855                 for i in $(seq 0 10000); do
16856                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16857                                 > /dev/null
16858                 done
16859
16860                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16861                         error "unlinkmany failed unlink"
16862                 last_rec=$(changelog_users $SINGLEMDS |
16863                         awk '/^current.index:/ { print $NF }')
16864                 echo last record $last_rec
16865                 (( last_rec == 0 )) && error "no changelog found"
16866         done
16867
16868 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16869         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16870
16871         __changelog_clear mds1 $cl_user1 0 &
16872         pid1=$!
16873         sleep 2
16874         __changelog_clear mds1 $cl_user1 0 ||
16875                 error "fail to cancel record for $cl_user1"
16876         wait $pid1
16877         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16878 }
16879 run_test 160n "Changelog destroy race"
16880
16881 test_160o() {
16882         local mdt="$(facet_svc $SINGLEMDS)"
16883
16884         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16885         remote_mds_nodsh && skip "remote MDS with nodsh"
16886         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16887                 skip "Need MDS version at least 2.14.52"
16888
16889         changelog_register --user test_160o -m unlnk+close+open ||
16890                 error "changelog_register failed"
16891
16892         do_facet $SINGLEMDS $LCTL --device $mdt \
16893                                 changelog_register -u "Tt3_-#" &&
16894                 error "bad symbols in name should fail"
16895
16896         do_facet $SINGLEMDS $LCTL --device $mdt \
16897                                 changelog_register -u test_160o &&
16898                 error "the same name registration should fail"
16899
16900         do_facet $SINGLEMDS $LCTL --device $mdt \
16901                         changelog_register -u test_160toolongname &&
16902                 error "too long name registration should fail"
16903
16904         changelog_chmask "MARK+HSM"
16905         lctl get_param mdd.*.changelog*mask
16906         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16907         changelog_users $SINGLEMDS | grep -q $cl_user ||
16908                 error "User $cl_user not found in changelog_users"
16909         #verify username
16910         echo $cl_user | grep -q test_160o ||
16911                 error "User $cl_user has no specific name 'test160o'"
16912
16913         # change something
16914         changelog_clear 0 || error "changelog_clear failed"
16915         # generate some changelog records to accumulate on MDT0
16916         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16917         touch $DIR/$tdir/$tfile                 # open 1
16918
16919         OPENS=$(changelog_dump | grep -c "OPEN")
16920         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16921
16922         # must be no MKDIR it wasn't set as user mask
16923         MKDIR=$(changelog_dump | grep -c "MKDIR")
16924         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16925
16926         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16927                                 mdd.$mdt.changelog_current_mask -n)
16928         # register maskless user
16929         changelog_register || error "changelog_register failed"
16930         # effective mask should be not changed because it is not minimal
16931         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16932                                 mdd.$mdt.changelog_current_mask -n)
16933         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16934         # set server mask to minimal value
16935         changelog_chmask "MARK"
16936         # check effective mask again, should be treated as DEFMASK now
16937         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16938                                 mdd.$mdt.changelog_current_mask -n)
16939         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16940
16941         do_facet $SINGLEMDS $LCTL --device $mdt \
16942                                 changelog_deregister -u test_160o ||
16943                 error "cannot deregister by name"
16944 }
16945 run_test 160o "changelog user name and mask"
16946
16947 test_160p() {
16948         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16949         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16950                 skip "Need MDS version at least 2.14.51"
16951         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16952         local cl_users
16953         local cl_user1
16954         local entry_count
16955
16956         # Create a user
16957         changelog_register || error "first changelog_register failed"
16958
16959         cl_users=(${CL_USERS[mds1]})
16960         cl_user1="${cl_users[0]}"
16961
16962         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16963         createmany -m $DIR/$tdir/$tfile 50 ||
16964                 error "create $DIR/$tdir/$tfile failed"
16965         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16966         rm -rf $DIR/$tdir
16967
16968         # check changelogs have been generated
16969         entry_count=$(changelog_dump | wc -l)
16970         ((entry_count != 0)) || error "no changelog entries found"
16971
16972         # remove changelog_users and check that orphan entries are removed
16973         stop mds1
16974         local dev=$(mdsdevname 1)
16975         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16976         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16977         entry_count=$(changelog_dump | wc -l)
16978         ((entry_count == 0)) ||
16979                 error "found $entry_count changelog entries, expected none"
16980 }
16981 run_test 160p "Changelog orphan cleanup with no users"
16982
16983 test_160q() {
16984         local mdt="$(facet_svc $SINGLEMDS)"
16985         local clu
16986
16987         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16988         remote_mds_nodsh && skip "remote MDS with nodsh"
16989         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16990                 skip "Need MDS version at least 2.14.54"
16991
16992         # set server mask to minimal value like server init does
16993         changelog_chmask "MARK"
16994         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16995                 error "changelog_register failed"
16996         # check effective mask again, should be treated as DEFMASK now
16997         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16998                                 mdd.$mdt.changelog_current_mask -n)
16999         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17000                 error "changelog_deregister failed"
17001         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17002 }
17003 run_test 160q "changelog effective mask is DEFMASK if not set"
17004
17005 test_160s() {
17006         remote_mds_nodsh && skip "remote MDS with nodsh"
17007         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17008                 skip "Need MDS version at least 2.14.55"
17009
17010         local mdts=$(comma_list $(mdts_nodes))
17011
17012         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17013         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17014                                        fail_val=$((24 * 3600 * 10))
17015
17016         # Create a user which is 10 days old
17017         changelog_register || error "first changelog_register failed"
17018         local cl_users
17019         declare -A cl_user1
17020         local i
17021
17022         # generate some changelog records to accumulate on each MDT
17023         # use all_char because created files should be evenly distributed
17024         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17025                 error "test_mkdir $tdir failed"
17026         for ((i = 0; i < MDSCOUNT; i++)); do
17027                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17028                         error "create $DIR/$tdir/d$i.1 failed"
17029         done
17030
17031         # check changelogs have been generated
17032         local nbcl=$(changelog_dump | wc -l)
17033         (( nbcl > 0 )) || error "no changelogs found"
17034
17035         # reduce the max_idle_indexes value to make sure we exceed it
17036         for param in "changelog_max_idle_indexes=2097446912" \
17037                      "changelog_max_idle_time=2592000" \
17038                      "changelog_gc=1" \
17039                      "changelog_min_gc_interval=2"; do
17040                 local MDT0=$(facet_svc $SINGLEMDS)
17041                 local var="${param%=*}"
17042                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17043
17044                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17045                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17046                         error "unable to set mdd.*.$param"
17047         done
17048
17049         local start=$SECONDS
17050         for i in $(seq $MDSCOUNT); do
17051                 cl_users=(${CL_USERS[mds$i]})
17052                 cl_user1[mds$i]="${cl_users[0]}"
17053
17054                 [[ -n "${cl_user1[mds$i]}" ]] ||
17055                         error "mds$i: no user registered"
17056         done
17057
17058         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17059         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17060
17061         # ensure we are past the previous changelog_min_gc_interval set above
17062         local sleep2=$((start + 2 - SECONDS))
17063         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17064
17065         # Generate one more changelog to trigger GC
17066         for ((i = 0; i < MDSCOUNT; i++)); do
17067                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17068                         error "create $DIR/$tdir/d$i.3 failed"
17069         done
17070
17071         # ensure gc thread is done
17072         for node in $(mdts_nodes); do
17073                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17074                         error "$node: GC-thread not done"
17075         done
17076
17077         do_nodes $mdts $LCTL set_param fail_loc=0
17078
17079         for (( i = 1; i <= MDSCOUNT; i++ )); do
17080                 # check cl_user1 is purged
17081                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17082                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17083         done
17084         return 0
17085 }
17086 run_test 160s "changelog garbage collect on idle records * time"
17087
17088 test_161a() {
17089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17090
17091         test_mkdir -c1 $DIR/$tdir
17092         cp /etc/hosts $DIR/$tdir/$tfile
17093         test_mkdir -c1 $DIR/$tdir/foo1
17094         test_mkdir -c1 $DIR/$tdir/foo2
17095         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17096         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17097         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17098         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17099         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17100         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17101                 $LFS fid2path $DIR $FID
17102                 error "bad link ea"
17103         fi
17104         # middle
17105         rm $DIR/$tdir/foo2/zachary
17106         # last
17107         rm $DIR/$tdir/foo2/thor
17108         # first
17109         rm $DIR/$tdir/$tfile
17110         # rename
17111         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17112         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17113                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17114         rm $DIR/$tdir/foo2/maggie
17115
17116         # overflow the EA
17117         local longname=$tfile.avg_len_is_thirty_two_
17118         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17119                 error_noexit 'failed to unlink many hardlinks'" EXIT
17120         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17121                 error "failed to hardlink many files"
17122         links=$($LFS fid2path $DIR $FID | wc -l)
17123         echo -n "${links}/1000 links in link EA"
17124         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17125 }
17126 run_test 161a "link ea sanity"
17127
17128 test_161b() {
17129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17130         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17131
17132         local MDTIDX=1
17133         local remote_dir=$DIR/$tdir/remote_dir
17134
17135         mkdir -p $DIR/$tdir
17136         $LFS mkdir -i $MDTIDX $remote_dir ||
17137                 error "create remote directory failed"
17138
17139         cp /etc/hosts $remote_dir/$tfile
17140         mkdir -p $remote_dir/foo1
17141         mkdir -p $remote_dir/foo2
17142         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17143         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17144         ln $remote_dir/$tfile $remote_dir/foo1/luna
17145         ln $remote_dir/$tfile $remote_dir/foo2/thor
17146
17147         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17148                      tr -d ']')
17149         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17150                 $LFS fid2path $DIR $FID
17151                 error "bad link ea"
17152         fi
17153         # middle
17154         rm $remote_dir/foo2/zachary
17155         # last
17156         rm $remote_dir/foo2/thor
17157         # first
17158         rm $remote_dir/$tfile
17159         # rename
17160         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17161         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17162         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17163                 $LFS fid2path $DIR $FID
17164                 error "bad link rename"
17165         fi
17166         rm $remote_dir/foo2/maggie
17167
17168         # overflow the EA
17169         local longname=filename_avg_len_is_thirty_two_
17170         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17171                 error "failed to hardlink many files"
17172         links=$($LFS fid2path $DIR $FID | wc -l)
17173         echo -n "${links}/1000 links in link EA"
17174         [[ ${links} -gt 60 ]] ||
17175                 error "expected at least 60 links in link EA"
17176         unlinkmany $remote_dir/foo2/$longname 1000 ||
17177         error "failed to unlink many hardlinks"
17178 }
17179 run_test 161b "link ea sanity under remote directory"
17180
17181 test_161c() {
17182         remote_mds_nodsh && skip "remote MDS with nodsh"
17183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17184         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17185                 skip "Need MDS version at least 2.1.5"
17186
17187         # define CLF_RENAME_LAST 0x0001
17188         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17189         changelog_register || error "changelog_register failed"
17190
17191         rm -rf $DIR/$tdir
17192         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17193         touch $DIR/$tdir/foo_161c
17194         touch $DIR/$tdir/bar_161c
17195         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17196         changelog_dump | grep RENME | tail -n 5
17197         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17198         changelog_clear 0 || error "changelog_clear failed"
17199         if [ x$flags != "x0x1" ]; then
17200                 error "flag $flags is not 0x1"
17201         fi
17202
17203         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17204         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17205         touch $DIR/$tdir/foo_161c
17206         touch $DIR/$tdir/bar_161c
17207         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17208         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17209         changelog_dump | grep RENME | tail -n 5
17210         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17211         changelog_clear 0 || error "changelog_clear failed"
17212         if [ x$flags != "x0x0" ]; then
17213                 error "flag $flags is not 0x0"
17214         fi
17215         echo "rename overwrite a target having nlink > 1," \
17216                 "changelog record has flags of $flags"
17217
17218         # rename doesn't overwrite a target (changelog flag 0x0)
17219         touch $DIR/$tdir/foo_161c
17220         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17221         changelog_dump | grep RENME | tail -n 5
17222         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17223         changelog_clear 0 || error "changelog_clear failed"
17224         if [ x$flags != "x0x0" ]; then
17225                 error "flag $flags is not 0x0"
17226         fi
17227         echo "rename doesn't overwrite a target," \
17228                 "changelog record has flags of $flags"
17229
17230         # define CLF_UNLINK_LAST 0x0001
17231         # unlink a file having nlink = 1 (changelog flag 0x1)
17232         rm -f $DIR/$tdir/foo2_161c
17233         changelog_dump | grep UNLNK | tail -n 5
17234         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17235         changelog_clear 0 || error "changelog_clear failed"
17236         if [ x$flags != "x0x1" ]; then
17237                 error "flag $flags is not 0x1"
17238         fi
17239         echo "unlink a file having nlink = 1," \
17240                 "changelog record has flags of $flags"
17241
17242         # unlink a file having nlink > 1 (changelog flag 0x0)
17243         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17244         rm -f $DIR/$tdir/foobar_161c
17245         changelog_dump | grep UNLNK | tail -n 5
17246         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17247         changelog_clear 0 || error "changelog_clear failed"
17248         if [ x$flags != "x0x0" ]; then
17249                 error "flag $flags is not 0x0"
17250         fi
17251         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17252 }
17253 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17254
17255 test_161d() {
17256         remote_mds_nodsh && skip "remote MDS with nodsh"
17257         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17258
17259         local pid
17260         local fid
17261
17262         changelog_register || error "changelog_register failed"
17263
17264         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17265         # interfer with $MOUNT/.lustre/fid/ access
17266         mkdir $DIR/$tdir
17267         [[ $? -eq 0 ]] || error "mkdir failed"
17268
17269         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17270         $LCTL set_param fail_loc=0x8000140c
17271         # 5s pause
17272         $LCTL set_param fail_val=5
17273
17274         # create file
17275         echo foofoo > $DIR/$tdir/$tfile &
17276         pid=$!
17277
17278         # wait for create to be delayed
17279         sleep 2
17280
17281         ps -p $pid
17282         [[ $? -eq 0 ]] || error "create should be blocked"
17283
17284         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17285         stack_trap "rm -f $tempfile"
17286         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17287         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17288         # some delay may occur during ChangeLog publishing and file read just
17289         # above, that could allow file write to happen finally
17290         [[ -s $tempfile ]] && echo "file should be empty"
17291
17292         $LCTL set_param fail_loc=0
17293
17294         wait $pid
17295         [[ $? -eq 0 ]] || error "create failed"
17296 }
17297 run_test 161d "create with concurrent .lustre/fid access"
17298
17299 check_path() {
17300         local expected="$1"
17301         shift
17302         local fid="$2"
17303
17304         local path
17305         path=$($LFS fid2path "$@")
17306         local rc=$?
17307
17308         if [ $rc -ne 0 ]; then
17309                 error "path looked up of '$expected' failed: rc=$rc"
17310         elif [ "$path" != "$expected" ]; then
17311                 error "path looked up '$path' instead of '$expected'"
17312         else
17313                 echo "FID '$fid' resolves to path '$path' as expected"
17314         fi
17315 }
17316
17317 test_162a() { # was test_162
17318         test_mkdir -p -c1 $DIR/$tdir/d2
17319         touch $DIR/$tdir/d2/$tfile
17320         touch $DIR/$tdir/d2/x1
17321         touch $DIR/$tdir/d2/x2
17322         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17323         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17324         # regular file
17325         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17326         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17327
17328         # softlink
17329         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17330         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17331         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17332
17333         # softlink to wrong file
17334         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17335         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17336         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17337
17338         # hardlink
17339         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17340         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17341         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17342         # fid2path dir/fsname should both work
17343         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17344         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17345
17346         # hardlink count: check that there are 2 links
17347         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17348         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17349
17350         # hardlink indexing: remove the first link
17351         rm $DIR/$tdir/d2/p/q/r/hlink
17352         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17353 }
17354 run_test 162a "path lookup sanity"
17355
17356 test_162b() {
17357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17359
17360         mkdir $DIR/$tdir
17361         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17362                                 error "create striped dir failed"
17363
17364         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17365                                         tail -n 1 | awk '{print $2}')
17366         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17367
17368         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17369         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17370
17371         # regular file
17372         for ((i=0;i<5;i++)); do
17373                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17374                         error "get fid for f$i failed"
17375                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17376
17377                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17378                         error "get fid for d$i failed"
17379                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17380         done
17381
17382         return 0
17383 }
17384 run_test 162b "striped directory path lookup sanity"
17385
17386 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17387 test_162c() {
17388         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17389                 skip "Need MDS version at least 2.7.51"
17390
17391         local lpath=$tdir.local
17392         local rpath=$tdir.remote
17393
17394         test_mkdir $DIR/$lpath
17395         test_mkdir $DIR/$rpath
17396
17397         for ((i = 0; i <= 101; i++)); do
17398                 lpath="$lpath/$i"
17399                 mkdir $DIR/$lpath
17400                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17401                         error "get fid for local directory $DIR/$lpath failed"
17402                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17403
17404                 rpath="$rpath/$i"
17405                 test_mkdir $DIR/$rpath
17406                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17407                         error "get fid for remote directory $DIR/$rpath failed"
17408                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17409         done
17410
17411         return 0
17412 }
17413 run_test 162c "fid2path works with paths 100 or more directories deep"
17414
17415 oalr_event_count() {
17416         local event="${1}"
17417         local trace="${2}"
17418
17419         awk -v name="${FSNAME}-OST0000" \
17420             -v event="${event}" \
17421             '$1 == "TRACE" && $2 == event && $3 == name' \
17422             "${trace}" |
17423         wc -l
17424 }
17425
17426 oalr_expect_event_count() {
17427         local event="${1}"
17428         local trace="${2}"
17429         local expect="${3}"
17430         local count
17431
17432         count=$(oalr_event_count "${event}" "${trace}")
17433         if ((count == expect)); then
17434                 return 0
17435         fi
17436
17437         error_noexit "${event} event count was '${count}', expected ${expect}"
17438         cat "${trace}" >&2
17439         exit 1
17440 }
17441
17442 cleanup_165() {
17443         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17444         stop ost1
17445         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17446 }
17447
17448 setup_165() {
17449         sync # Flush previous IOs so we can count log entries.
17450         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17451         stack_trap cleanup_165 EXIT
17452 }
17453
17454 test_165a() {
17455         local trace="/tmp/${tfile}.trace"
17456         local rc
17457         local count
17458
17459         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17460                 skip "OFD access log unsupported"
17461
17462         setup_165
17463         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17464         sleep 5
17465
17466         do_facet ost1 ofd_access_log_reader --list
17467         stop ost1
17468
17469         do_facet ost1 killall -TERM ofd_access_log_reader
17470         wait
17471         rc=$?
17472
17473         if ((rc != 0)); then
17474                 error "ofd_access_log_reader exited with rc = '${rc}'"
17475         fi
17476
17477         # Parse trace file for discovery events:
17478         oalr_expect_event_count alr_log_add "${trace}" 1
17479         oalr_expect_event_count alr_log_eof "${trace}" 1
17480         oalr_expect_event_count alr_log_free "${trace}" 1
17481 }
17482 run_test 165a "ofd access log discovery"
17483
17484 test_165b() {
17485         local trace="/tmp/${tfile}.trace"
17486         local file="${DIR}/${tfile}"
17487         local pfid1
17488         local pfid2
17489         local -a entry
17490         local rc
17491         local count
17492         local size
17493         local flags
17494
17495         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17496                 skip "OFD access log unsupported"
17497
17498         setup_165
17499         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17500         sleep 5
17501
17502         do_facet ost1 ofd_access_log_reader --list
17503
17504         lfs setstripe -c 1 -i 0 "${file}"
17505         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17506                 error "cannot create '${file}'"
17507
17508         sleep 5
17509         do_facet ost1 killall -TERM ofd_access_log_reader
17510         wait
17511         rc=$?
17512
17513         if ((rc != 0)); then
17514                 error "ofd_access_log_reader exited with rc = '${rc}'"
17515         fi
17516
17517         oalr_expect_event_count alr_log_entry "${trace}" 1
17518
17519         pfid1=$($LFS path2fid "${file}")
17520
17521         # 1     2             3   4    5     6   7    8    9     10
17522         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17523         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17524
17525         echo "entry = '${entry[*]}'" >&2
17526
17527         pfid2=${entry[4]}
17528         if [[ "${pfid1}" != "${pfid2}" ]]; then
17529                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17530         fi
17531
17532         size=${entry[8]}
17533         if ((size != 1048576)); then
17534                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17535         fi
17536
17537         flags=${entry[10]}
17538         if [[ "${flags}" != "w" ]]; then
17539                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17540         fi
17541
17542         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17543         sleep 5
17544
17545         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17546                 error "cannot read '${file}'"
17547         sleep 5
17548
17549         do_facet ost1 killall -TERM ofd_access_log_reader
17550         wait
17551         rc=$?
17552
17553         if ((rc != 0)); then
17554                 error "ofd_access_log_reader exited with rc = '${rc}'"
17555         fi
17556
17557         oalr_expect_event_count alr_log_entry "${trace}" 1
17558
17559         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17560         echo "entry = '${entry[*]}'" >&2
17561
17562         pfid2=${entry[4]}
17563         if [[ "${pfid1}" != "${pfid2}" ]]; then
17564                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17565         fi
17566
17567         size=${entry[8]}
17568         if ((size != 524288)); then
17569                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17570         fi
17571
17572         flags=${entry[10]}
17573         if [[ "${flags}" != "r" ]]; then
17574                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17575         fi
17576 }
17577 run_test 165b "ofd access log entries are produced and consumed"
17578
17579 test_165c() {
17580         local trace="/tmp/${tfile}.trace"
17581         local file="${DIR}/${tdir}/${tfile}"
17582
17583         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17584                 skip "OFD access log unsupported"
17585
17586         test_mkdir "${DIR}/${tdir}"
17587
17588         setup_165
17589         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17590         sleep 5
17591
17592         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17593
17594         # 4096 / 64 = 64. Create twice as many entries.
17595         for ((i = 0; i < 128; i++)); do
17596                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17597                         error "cannot create file"
17598         done
17599
17600         sync
17601
17602         do_facet ost1 killall -TERM ofd_access_log_reader
17603         wait
17604         rc=$?
17605         if ((rc != 0)); then
17606                 error "ofd_access_log_reader exited with rc = '${rc}'"
17607         fi
17608
17609         unlinkmany  "${file}-%d" 128
17610 }
17611 run_test 165c "full ofd access logs do not block IOs"
17612
17613 oal_get_read_count() {
17614         local stats="$1"
17615
17616         # STATS lustre-OST0001 alr_read_count 1
17617
17618         do_facet ost1 cat "${stats}" |
17619         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17620              END { print count; }'
17621 }
17622
17623 oal_expect_read_count() {
17624         local stats="$1"
17625         local count
17626         local expect="$2"
17627
17628         # Ask ofd_access_log_reader to write stats.
17629         do_facet ost1 killall -USR1 ofd_access_log_reader
17630
17631         # Allow some time for things to happen.
17632         sleep 1
17633
17634         count=$(oal_get_read_count "${stats}")
17635         if ((count == expect)); then
17636                 return 0
17637         fi
17638
17639         error_noexit "bad read count, got ${count}, expected ${expect}"
17640         do_facet ost1 cat "${stats}" >&2
17641         exit 1
17642 }
17643
17644 test_165d() {
17645         local stats="/tmp/${tfile}.stats"
17646         local file="${DIR}/${tdir}/${tfile}"
17647         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17648
17649         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17650                 skip "OFD access log unsupported"
17651
17652         test_mkdir "${DIR}/${tdir}"
17653
17654         setup_165
17655         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17656         sleep 5
17657
17658         lfs setstripe -c 1 -i 0 "${file}"
17659
17660         do_facet ost1 lctl set_param "${param}=rw"
17661         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17662                 error "cannot create '${file}'"
17663         oal_expect_read_count "${stats}" 1
17664
17665         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17666                 error "cannot read '${file}'"
17667         oal_expect_read_count "${stats}" 2
17668
17669         do_facet ost1 lctl set_param "${param}=r"
17670         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17671                 error "cannot create '${file}'"
17672         oal_expect_read_count "${stats}" 2
17673
17674         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17675                 error "cannot read '${file}'"
17676         oal_expect_read_count "${stats}" 3
17677
17678         do_facet ost1 lctl set_param "${param}=w"
17679         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17680                 error "cannot create '${file}'"
17681         oal_expect_read_count "${stats}" 4
17682
17683         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17684                 error "cannot read '${file}'"
17685         oal_expect_read_count "${stats}" 4
17686
17687         do_facet ost1 lctl set_param "${param}=0"
17688         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17689                 error "cannot create '${file}'"
17690         oal_expect_read_count "${stats}" 4
17691
17692         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17693                 error "cannot read '${file}'"
17694         oal_expect_read_count "${stats}" 4
17695
17696         do_facet ost1 killall -TERM ofd_access_log_reader
17697         wait
17698         rc=$?
17699         if ((rc != 0)); then
17700                 error "ofd_access_log_reader exited with rc = '${rc}'"
17701         fi
17702 }
17703 run_test 165d "ofd_access_log mask works"
17704
17705 test_165e() {
17706         local stats="/tmp/${tfile}.stats"
17707         local file0="${DIR}/${tdir}-0/${tfile}"
17708         local file1="${DIR}/${tdir}-1/${tfile}"
17709
17710         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17711                 skip "OFD access log unsupported"
17712
17713         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17714
17715         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17716         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17717
17718         lfs setstripe -c 1 -i 0 "${file0}"
17719         lfs setstripe -c 1 -i 0 "${file1}"
17720
17721         setup_165
17722         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17723         sleep 5
17724
17725         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17726                 error "cannot create '${file0}'"
17727         sync
17728         oal_expect_read_count "${stats}" 0
17729
17730         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17731                 error "cannot create '${file1}'"
17732         sync
17733         oal_expect_read_count "${stats}" 1
17734
17735         do_facet ost1 killall -TERM ofd_access_log_reader
17736         wait
17737         rc=$?
17738         if ((rc != 0)); then
17739                 error "ofd_access_log_reader exited with rc = '${rc}'"
17740         fi
17741 }
17742 run_test 165e "ofd_access_log MDT index filter works"
17743
17744 test_165f() {
17745         local trace="/tmp/${tfile}.trace"
17746         local rc
17747         local count
17748
17749         setup_165
17750         do_facet ost1 timeout 60 ofd_access_log_reader \
17751                 --exit-on-close --debug=- --trace=- > "${trace}" &
17752         sleep 5
17753         stop ost1
17754
17755         wait
17756         rc=$?
17757
17758         if ((rc != 0)); then
17759                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17760                 cat "${trace}"
17761                 exit 1
17762         fi
17763 }
17764 run_test 165f "ofd_access_log_reader --exit-on-close works"
17765
17766 test_169() {
17767         # do directio so as not to populate the page cache
17768         log "creating a 10 Mb file"
17769         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17770                 error "multiop failed while creating a file"
17771         log "starting reads"
17772         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17773         log "truncating the file"
17774         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17775                 error "multiop failed while truncating the file"
17776         log "killing dd"
17777         kill %+ || true # reads might have finished
17778         echo "wait until dd is finished"
17779         wait
17780         log "removing the temporary file"
17781         rm -rf $DIR/$tfile || error "tmp file removal failed"
17782 }
17783 run_test 169 "parallel read and truncate should not deadlock"
17784
17785 test_170() {
17786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17787
17788         $LCTL clear     # bug 18514
17789         $LCTL debug_daemon start $TMP/${tfile}_log_good
17790         touch $DIR/$tfile
17791         $LCTL debug_daemon stop
17792         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17793                 error "sed failed to read log_good"
17794
17795         $LCTL debug_daemon start $TMP/${tfile}_log_good
17796         rm -rf $DIR/$tfile
17797         $LCTL debug_daemon stop
17798
17799         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17800                error "lctl df log_bad failed"
17801
17802         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17803         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17804
17805         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17806         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17807
17808         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17809                 error "bad_line good_line1 good_line2 are empty"
17810
17811         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17812         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17813         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17814
17815         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17816         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17817         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17818
17819         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17820                 error "bad_line_new good_line_new are empty"
17821
17822         local expected_good=$((good_line1 + good_line2*2))
17823
17824         rm -f $TMP/${tfile}*
17825         # LU-231, short malformed line may not be counted into bad lines
17826         if [ $bad_line -ne $bad_line_new ] &&
17827                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17828                 error "expected $bad_line bad lines, but got $bad_line_new"
17829                 return 1
17830         fi
17831
17832         if [ $expected_good -ne $good_line_new ]; then
17833                 error "expected $expected_good good lines, but got $good_line_new"
17834                 return 2
17835         fi
17836         true
17837 }
17838 run_test 170 "test lctl df to handle corrupted log ====================="
17839
17840 test_171() { # bug20592
17841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17842
17843         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17844         $LCTL set_param fail_loc=0x50e
17845         $LCTL set_param fail_val=3000
17846         multiop_bg_pause $DIR/$tfile O_s || true
17847         local MULTIPID=$!
17848         kill -USR1 $MULTIPID
17849         # cause log dump
17850         sleep 3
17851         wait $MULTIPID
17852         if dmesg | grep "recursive fault"; then
17853                 error "caught a recursive fault"
17854         fi
17855         $LCTL set_param fail_loc=0
17856         true
17857 }
17858 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17859
17860 test_172() {
17861
17862         #define OBD_FAIL_OBD_CLEANUP  0x60e
17863         $LCTL set_param fail_loc=0x60e
17864         umount $MOUNT || error "umount $MOUNT failed"
17865         stack_trap "mount_client $MOUNT"
17866
17867         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17868                 error "no client OBDs are remained"
17869
17870         $LCTL dl | while read devno state type name foo; do
17871                 case $type in
17872                 lov|osc|lmv|mdc)
17873                         $LCTL --device $name cleanup
17874                         $LCTL --device $name detach
17875                         ;;
17876                 *)
17877                         # skip server devices
17878                         ;;
17879                 esac
17880         done
17881
17882         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17883                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17884                 error "some client OBDs are still remained"
17885         fi
17886
17887 }
17888 run_test 172 "manual device removal with lctl cleanup/detach ======"
17889
17890 # it would be good to share it with obdfilter-survey/iokit-libecho code
17891 setup_obdecho_osc () {
17892         local rc=0
17893         local ost_nid=$1
17894         local obdfilter_name=$2
17895         echo "Creating new osc for $obdfilter_name on $ost_nid"
17896         # make sure we can find loopback nid
17897         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17898
17899         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17900                            ${obdfilter_name}_osc_UUID || rc=2; }
17901         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17902                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17903         return $rc
17904 }
17905
17906 cleanup_obdecho_osc () {
17907         local obdfilter_name=$1
17908         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17909         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17910         return 0
17911 }
17912
17913 obdecho_test() {
17914         local OBD=$1
17915         local node=$2
17916         local pages=${3:-64}
17917         local rc=0
17918         local id
17919
17920         local count=10
17921         local obd_size=$(get_obd_size $node $OBD)
17922         local page_size=$(get_page_size $node)
17923         if [[ -n "$obd_size" ]]; then
17924                 local new_count=$((obd_size / (pages * page_size / 1024)))
17925                 [[ $new_count -ge $count ]] || count=$new_count
17926         fi
17927
17928         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17929         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17930                            rc=2; }
17931         if [ $rc -eq 0 ]; then
17932             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17933             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17934         fi
17935         echo "New object id is $id"
17936         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17937                            rc=4; }
17938         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17939                            "test_brw $count w v $pages $id" || rc=4; }
17940         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17941                            rc=4; }
17942         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17943                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17944         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17945                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17946         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17947         return $rc
17948 }
17949
17950 test_180a() {
17951         skip "obdecho on osc is no longer supported"
17952 }
17953 run_test 180a "test obdecho on osc"
17954
17955 test_180b() {
17956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17957         remote_ost_nodsh && skip "remote OST with nodsh"
17958
17959         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17960                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17961                 error "failed to load module obdecho"
17962
17963         local target=$(do_facet ost1 $LCTL dl |
17964                        awk '/obdfilter/ { print $4; exit; }')
17965
17966         if [ -n "$target" ]; then
17967                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17968         else
17969                 do_facet ost1 $LCTL dl
17970                 error "there is no obdfilter target on ost1"
17971         fi
17972 }
17973 run_test 180b "test obdecho directly on obdfilter"
17974
17975 test_180c() { # LU-2598
17976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17977         remote_ost_nodsh && skip "remote OST with nodsh"
17978         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17979                 skip "Need MDS version at least 2.4.0"
17980
17981         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17982                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17983                 error "failed to load module obdecho"
17984
17985         local target=$(do_facet ost1 $LCTL dl |
17986                        awk '/obdfilter/ { print $4; exit; }')
17987
17988         if [ -n "$target" ]; then
17989                 local pages=16384 # 64MB bulk I/O RPC size
17990
17991                 obdecho_test "$target" ost1 "$pages" ||
17992                         error "obdecho_test with pages=$pages failed with $?"
17993         else
17994                 do_facet ost1 $LCTL dl
17995                 error "there is no obdfilter target on ost1"
17996         fi
17997 }
17998 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17999
18000 test_181() { # bug 22177
18001         test_mkdir $DIR/$tdir
18002         # create enough files to index the directory
18003         createmany -o $DIR/$tdir/foobar 4000
18004         # print attributes for debug purpose
18005         lsattr -d .
18006         # open dir
18007         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18008         MULTIPID=$!
18009         # remove the files & current working dir
18010         unlinkmany $DIR/$tdir/foobar 4000
18011         rmdir $DIR/$tdir
18012         kill -USR1 $MULTIPID
18013         wait $MULTIPID
18014         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18015         return 0
18016 }
18017 run_test 181 "Test open-unlinked dir ========================"
18018
18019 test_182a() {
18020         local fcount=1000
18021         local tcount=10
18022
18023         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18024
18025         $LCTL set_param mdc.*.rpc_stats=clear
18026
18027         for (( i = 0; i < $tcount; i++ )) ; do
18028                 mkdir $DIR/$tdir/$i
18029         done
18030
18031         for (( i = 0; i < $tcount; i++ )) ; do
18032                 createmany -o $DIR/$tdir/$i/f- $fcount &
18033         done
18034         wait
18035
18036         for (( i = 0; i < $tcount; i++ )) ; do
18037                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18038         done
18039         wait
18040
18041         $LCTL get_param mdc.*.rpc_stats
18042
18043         rm -rf $DIR/$tdir
18044 }
18045 run_test 182a "Test parallel modify metadata operations from mdc"
18046
18047 test_182b() {
18048         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18049         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18050         local dcount=1000
18051         local tcount=10
18052         local stime
18053         local etime
18054         local delta
18055
18056         do_facet mds1 $LCTL list_param \
18057                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18058                 skip "MDS lacks parallel RPC handling"
18059
18060         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18061
18062         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18063                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18064
18065         stime=$(date +%s)
18066         createmany -i 0 -d $DIR/$tdir/t- $tcount
18067
18068         for (( i = 0; i < $tcount; i++ )) ; do
18069                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18070         done
18071         wait
18072         etime=$(date +%s)
18073         delta=$((etime - stime))
18074         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18075
18076         stime=$(date +%s)
18077         for (( i = 0; i < $tcount; i++ )) ; do
18078                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18079         done
18080         wait
18081         etime=$(date +%s)
18082         delta=$((etime - stime))
18083         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18084
18085         rm -rf $DIR/$tdir
18086
18087         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18088
18089         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18090
18091         stime=$(date +%s)
18092         createmany -i 0 -d $DIR/$tdir/t- $tcount
18093
18094         for (( i = 0; i < $tcount; i++ )) ; do
18095                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18096         done
18097         wait
18098         etime=$(date +%s)
18099         delta=$((etime - stime))
18100         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18101
18102         stime=$(date +%s)
18103         for (( i = 0; i < $tcount; i++ )) ; do
18104                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18105         done
18106         wait
18107         etime=$(date +%s)
18108         delta=$((etime - stime))
18109         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18110
18111         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18112 }
18113 run_test 182b "Test parallel modify metadata operations from osp"
18114
18115 test_183() { # LU-2275
18116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18117         remote_mds_nodsh && skip "remote MDS with nodsh"
18118         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18119                 skip "Need MDS version at least 2.3.56"
18120
18121         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18122         echo aaa > $DIR/$tdir/$tfile
18123
18124 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18125         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18126
18127         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18128         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18129
18130         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18131
18132         # Flush negative dentry cache
18133         touch $DIR/$tdir/$tfile
18134
18135         # We are not checking for any leaked references here, they'll
18136         # become evident next time we do cleanup with module unload.
18137         rm -rf $DIR/$tdir
18138 }
18139 run_test 183 "No crash or request leak in case of strange dispositions ========"
18140
18141 # test suite 184 is for LU-2016, LU-2017
18142 test_184a() {
18143         check_swap_layouts_support
18144
18145         dir0=$DIR/$tdir/$testnum
18146         test_mkdir -p -c1 $dir0
18147         ref1=/etc/passwd
18148         ref2=/etc/group
18149         file1=$dir0/f1
18150         file2=$dir0/f2
18151         $LFS setstripe -c1 $file1
18152         cp $ref1 $file1
18153         $LFS setstripe -c2 $file2
18154         cp $ref2 $file2
18155         gen1=$($LFS getstripe -g $file1)
18156         gen2=$($LFS getstripe -g $file2)
18157
18158         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18159         gen=$($LFS getstripe -g $file1)
18160         [[ $gen1 != $gen ]] ||
18161                 error "Layout generation on $file1 does not change"
18162         gen=$($LFS getstripe -g $file2)
18163         [[ $gen2 != $gen ]] ||
18164                 error "Layout generation on $file2 does not change"
18165
18166         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18167         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18168
18169         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18170 }
18171 run_test 184a "Basic layout swap"
18172
18173 test_184b() {
18174         check_swap_layouts_support
18175
18176         dir0=$DIR/$tdir/$testnum
18177         mkdir -p $dir0 || error "creating dir $dir0"
18178         file1=$dir0/f1
18179         file2=$dir0/f2
18180         file3=$dir0/f3
18181         dir1=$dir0/d1
18182         dir2=$dir0/d2
18183         mkdir $dir1 $dir2
18184         $LFS setstripe -c1 $file1
18185         $LFS setstripe -c2 $file2
18186         $LFS setstripe -c1 $file3
18187         chown $RUNAS_ID $file3
18188         gen1=$($LFS getstripe -g $file1)
18189         gen2=$($LFS getstripe -g $file2)
18190
18191         $LFS swap_layouts $dir1 $dir2 &&
18192                 error "swap of directories layouts should fail"
18193         $LFS swap_layouts $dir1 $file1 &&
18194                 error "swap of directory and file layouts should fail"
18195         $RUNAS $LFS swap_layouts $file1 $file2 &&
18196                 error "swap of file we cannot write should fail"
18197         $LFS swap_layouts $file1 $file3 &&
18198                 error "swap of file with different owner should fail"
18199         /bin/true # to clear error code
18200 }
18201 run_test 184b "Forbidden layout swap (will generate errors)"
18202
18203 test_184c() {
18204         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18205         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18206         check_swap_layouts_support
18207         check_swap_layout_no_dom $DIR
18208
18209         local dir0=$DIR/$tdir/$testnum
18210         mkdir -p $dir0 || error "creating dir $dir0"
18211
18212         local ref1=$dir0/ref1
18213         local ref2=$dir0/ref2
18214         local file1=$dir0/file1
18215         local file2=$dir0/file2
18216         # create a file large enough for the concurrent test
18217         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18218         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18219         echo "ref file size: ref1($(stat -c %s $ref1))," \
18220              "ref2($(stat -c %s $ref2))"
18221
18222         cp $ref2 $file2
18223         dd if=$ref1 of=$file1 bs=16k &
18224         local DD_PID=$!
18225
18226         # Make sure dd starts to copy file, but wait at most 5 seconds
18227         local loops=0
18228         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18229
18230         $LFS swap_layouts $file1 $file2
18231         local rc=$?
18232         wait $DD_PID
18233         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18234         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18235
18236         # how many bytes copied before swapping layout
18237         local copied=$(stat -c %s $file2)
18238         local remaining=$(stat -c %s $ref1)
18239         remaining=$((remaining - copied))
18240         echo "Copied $copied bytes before swapping layout..."
18241
18242         cmp -n $copied $file1 $ref2 | grep differ &&
18243                 error "Content mismatch [0, $copied) of ref2 and file1"
18244         cmp -n $copied $file2 $ref1 ||
18245                 error "Content mismatch [0, $copied) of ref1 and file2"
18246         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18247                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18248
18249         # clean up
18250         rm -f $ref1 $ref2 $file1 $file2
18251 }
18252 run_test 184c "Concurrent write and layout swap"
18253
18254 test_184d() {
18255         check_swap_layouts_support
18256         check_swap_layout_no_dom $DIR
18257         [ -z "$(which getfattr 2>/dev/null)" ] &&
18258                 skip_env "no getfattr command"
18259
18260         local file1=$DIR/$tdir/$tfile-1
18261         local file2=$DIR/$tdir/$tfile-2
18262         local file3=$DIR/$tdir/$tfile-3
18263         local lovea1
18264         local lovea2
18265
18266         mkdir -p $DIR/$tdir
18267         touch $file1 || error "create $file1 failed"
18268         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18269                 error "create $file2 failed"
18270         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18271                 error "create $file3 failed"
18272         lovea1=$(get_layout_param $file1)
18273
18274         $LFS swap_layouts $file2 $file3 ||
18275                 error "swap $file2 $file3 layouts failed"
18276         $LFS swap_layouts $file1 $file2 ||
18277                 error "swap $file1 $file2 layouts failed"
18278
18279         lovea2=$(get_layout_param $file2)
18280         echo "$lovea1"
18281         echo "$lovea2"
18282         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18283
18284         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18285         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18286 }
18287 run_test 184d "allow stripeless layouts swap"
18288
18289 test_184e() {
18290         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18291                 skip "Need MDS version at least 2.6.94"
18292         check_swap_layouts_support
18293         check_swap_layout_no_dom $DIR
18294         [ -z "$(which getfattr 2>/dev/null)" ] &&
18295                 skip_env "no getfattr command"
18296
18297         local file1=$DIR/$tdir/$tfile-1
18298         local file2=$DIR/$tdir/$tfile-2
18299         local file3=$DIR/$tdir/$tfile-3
18300         local lovea
18301
18302         mkdir -p $DIR/$tdir
18303         touch $file1 || error "create $file1 failed"
18304         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18305                 error "create $file2 failed"
18306         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18307                 error "create $file3 failed"
18308
18309         $LFS swap_layouts $file1 $file2 ||
18310                 error "swap $file1 $file2 layouts failed"
18311
18312         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18313         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18314
18315         echo 123 > $file1 || error "Should be able to write into $file1"
18316
18317         $LFS swap_layouts $file1 $file3 ||
18318                 error "swap $file1 $file3 layouts failed"
18319
18320         echo 123 > $file1 || error "Should be able to write into $file1"
18321
18322         rm -rf $file1 $file2 $file3
18323 }
18324 run_test 184e "Recreate layout after stripeless layout swaps"
18325
18326 test_184f() {
18327         # Create a file with name longer than sizeof(struct stat) ==
18328         # 144 to see if we can get chars from the file name to appear
18329         # in the returned striping. Note that 'f' == 0x66.
18330         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18331
18332         mkdir -p $DIR/$tdir
18333         mcreate $DIR/$tdir/$file
18334         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18335                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18336         fi
18337 }
18338 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18339
18340 test_185() { # LU-2441
18341         # LU-3553 - no volatile file support in old servers
18342         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18343                 skip "Need MDS version at least 2.3.60"
18344
18345         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18346         touch $DIR/$tdir/spoo
18347         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18348         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18349                 error "cannot create/write a volatile file"
18350         [ "$FILESET" == "" ] &&
18351         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18352                 error "FID is still valid after close"
18353
18354         multiop_bg_pause $DIR/$tdir vVw4096_c
18355         local multi_pid=$!
18356
18357         local OLD_IFS=$IFS
18358         IFS=":"
18359         local fidv=($fid)
18360         IFS=$OLD_IFS
18361         # assume that the next FID for this client is sequential, since stdout
18362         # is unfortunately eaten by multiop_bg_pause
18363         local n=$((${fidv[1]} + 1))
18364         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18365         if [ "$FILESET" == "" ]; then
18366                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18367                         error "FID is missing before close"
18368         fi
18369         kill -USR1 $multi_pid
18370         # 1 second delay, so if mtime change we will see it
18371         sleep 1
18372         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18373         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18374 }
18375 run_test 185 "Volatile file support"
18376
18377 function create_check_volatile() {
18378         local idx=$1
18379         local tgt
18380
18381         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18382         local PID=$!
18383         sleep 1
18384         local FID=$(cat /tmp/${tfile}.fid)
18385         [ "$FID" == "" ] && error "can't get FID for volatile"
18386         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18387         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18388         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18389         kill -USR1 $PID
18390         wait
18391         sleep 1
18392         cancel_lru_locks mdc # flush opencache
18393         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18394         return 0
18395 }
18396
18397 test_185a(){
18398         # LU-12516 - volatile creation via .lustre
18399         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18400                 skip "Need MDS version at least 2.3.55"
18401
18402         create_check_volatile 0
18403         [ $MDSCOUNT -lt 2 ] && return 0
18404
18405         # DNE case
18406         create_check_volatile 1
18407
18408         return 0
18409 }
18410 run_test 185a "Volatile file creation in .lustre/fid/"
18411
18412 test_187a() {
18413         remote_mds_nodsh && skip "remote MDS with nodsh"
18414         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18415                 skip "Need MDS version at least 2.3.0"
18416
18417         local dir0=$DIR/$tdir/$testnum
18418         mkdir -p $dir0 || error "creating dir $dir0"
18419
18420         local file=$dir0/file1
18421         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18422         local dv1=$($LFS data_version $file)
18423         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18424         local dv2=$($LFS data_version $file)
18425         [[ $dv1 != $dv2 ]] ||
18426                 error "data version did not change on write $dv1 == $dv2"
18427
18428         # clean up
18429         rm -f $file1
18430 }
18431 run_test 187a "Test data version change"
18432
18433 test_187b() {
18434         remote_mds_nodsh && skip "remote MDS with nodsh"
18435         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18436                 skip "Need MDS version at least 2.3.0"
18437
18438         local dir0=$DIR/$tdir/$testnum
18439         mkdir -p $dir0 || error "creating dir $dir0"
18440
18441         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18442         [[ ${DV[0]} != ${DV[1]} ]] ||
18443                 error "data version did not change on write"\
18444                       " ${DV[0]} == ${DV[1]}"
18445
18446         # clean up
18447         rm -f $file1
18448 }
18449 run_test 187b "Test data version change on volatile file"
18450
18451 test_200() {
18452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18453         remote_mgs_nodsh && skip "remote MGS with nodsh"
18454         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18455
18456         local POOL=${POOL:-cea1}
18457         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18458         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18459         # Pool OST targets
18460         local first_ost=0
18461         local last_ost=$(($OSTCOUNT - 1))
18462         local ost_step=2
18463         local ost_list=$(seq $first_ost $ost_step $last_ost)
18464         local ost_range="$first_ost $last_ost $ost_step"
18465         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18466         local file_dir=$POOL_ROOT/file_tst
18467         local subdir=$test_path/subdir
18468         local rc=0
18469
18470         while : ; do
18471                 # former test_200a test_200b
18472                 pool_add $POOL                          || { rc=$? ; break; }
18473                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18474                 # former test_200c test_200d
18475                 mkdir -p $test_path
18476                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18477                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18478                 mkdir -p $subdir
18479                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18480                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18481                                                         || { rc=$? ; break; }
18482                 # former test_200e test_200f
18483                 local files=$((OSTCOUNT*3))
18484                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18485                                                         || { rc=$? ; break; }
18486                 pool_create_files $POOL $file_dir $files "$ost_list" \
18487                                                         || { rc=$? ; break; }
18488                 # former test_200g test_200h
18489                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18490                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18491
18492                 # former test_201a test_201b test_201c
18493                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18494
18495                 local f=$test_path/$tfile
18496                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18497                 pool_remove $POOL $f                    || { rc=$? ; break; }
18498                 break
18499         done
18500
18501         destroy_test_pools
18502
18503         return $rc
18504 }
18505 run_test 200 "OST pools"
18506
18507 # usage: default_attr <count | size | offset>
18508 default_attr() {
18509         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18510 }
18511
18512 # usage: check_default_stripe_attr
18513 check_default_stripe_attr() {
18514         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18515         case $1 in
18516         --stripe-count|-c)
18517                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18518         --stripe-size|-S)
18519                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18520         --stripe-index|-i)
18521                 EXPECTED=-1;;
18522         *)
18523                 error "unknown getstripe attr '$1'"
18524         esac
18525
18526         [ $ACTUAL == $EXPECTED ] ||
18527                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18528 }
18529
18530 test_204a() {
18531         test_mkdir $DIR/$tdir
18532         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18533
18534         check_default_stripe_attr --stripe-count
18535         check_default_stripe_attr --stripe-size
18536         check_default_stripe_attr --stripe-index
18537 }
18538 run_test 204a "Print default stripe attributes"
18539
18540 test_204b() {
18541         test_mkdir $DIR/$tdir
18542         $LFS setstripe --stripe-count 1 $DIR/$tdir
18543
18544         check_default_stripe_attr --stripe-size
18545         check_default_stripe_attr --stripe-index
18546 }
18547 run_test 204b "Print default stripe size and offset"
18548
18549 test_204c() {
18550         test_mkdir $DIR/$tdir
18551         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18552
18553         check_default_stripe_attr --stripe-count
18554         check_default_stripe_attr --stripe-index
18555 }
18556 run_test 204c "Print default stripe count and offset"
18557
18558 test_204d() {
18559         test_mkdir $DIR/$tdir
18560         $LFS setstripe --stripe-index 0 $DIR/$tdir
18561
18562         check_default_stripe_attr --stripe-count
18563         check_default_stripe_attr --stripe-size
18564 }
18565 run_test 204d "Print default stripe count and size"
18566
18567 test_204e() {
18568         test_mkdir $DIR/$tdir
18569         $LFS setstripe -d $DIR/$tdir
18570
18571         check_default_stripe_attr --stripe-count --raw
18572         check_default_stripe_attr --stripe-size --raw
18573         check_default_stripe_attr --stripe-index --raw
18574 }
18575 run_test 204e "Print raw stripe attributes"
18576
18577 test_204f() {
18578         test_mkdir $DIR/$tdir
18579         $LFS setstripe --stripe-count 1 $DIR/$tdir
18580
18581         check_default_stripe_attr --stripe-size --raw
18582         check_default_stripe_attr --stripe-index --raw
18583 }
18584 run_test 204f "Print raw stripe size and offset"
18585
18586 test_204g() {
18587         test_mkdir $DIR/$tdir
18588         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18589
18590         check_default_stripe_attr --stripe-count --raw
18591         check_default_stripe_attr --stripe-index --raw
18592 }
18593 run_test 204g "Print raw stripe count and offset"
18594
18595 test_204h() {
18596         test_mkdir $DIR/$tdir
18597         $LFS setstripe --stripe-index 0 $DIR/$tdir
18598
18599         check_default_stripe_attr --stripe-count --raw
18600         check_default_stripe_attr --stripe-size --raw
18601 }
18602 run_test 204h "Print raw stripe count and size"
18603
18604 # Figure out which job scheduler is being used, if any,
18605 # or use a fake one
18606 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18607         JOBENV=SLURM_JOB_ID
18608 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18609         JOBENV=LSB_JOBID
18610 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18611         JOBENV=PBS_JOBID
18612 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18613         JOBENV=LOADL_STEP_ID
18614 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18615         JOBENV=JOB_ID
18616 else
18617         $LCTL list_param jobid_name > /dev/null 2>&1
18618         if [ $? -eq 0 ]; then
18619                 JOBENV=nodelocal
18620         else
18621                 JOBENV=FAKE_JOBID
18622         fi
18623 fi
18624 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18625
18626 verify_jobstats() {
18627         local cmd=($1)
18628         shift
18629         local facets="$@"
18630
18631 # we don't really need to clear the stats for this test to work, since each
18632 # command has a unique jobid, but it makes debugging easier if needed.
18633 #       for facet in $facets; do
18634 #               local dev=$(convert_facet2label $facet)
18635 #               # clear old jobstats
18636 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18637 #       done
18638
18639         # use a new JobID for each test, or we might see an old one
18640         [ "$JOBENV" = "FAKE_JOBID" ] &&
18641                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18642
18643         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18644
18645         [ "$JOBENV" = "nodelocal" ] && {
18646                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18647                 $LCTL set_param jobid_name=$FAKE_JOBID
18648                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18649         }
18650
18651         log "Test: ${cmd[*]}"
18652         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18653
18654         if [ $JOBENV = "FAKE_JOBID" ]; then
18655                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18656         else
18657                 ${cmd[*]}
18658         fi
18659
18660         # all files are created on OST0000
18661         for facet in $facets; do
18662                 local stats="*.$(convert_facet2label $facet).job_stats"
18663
18664                 # strip out libtool wrappers for in-tree executables
18665                 if (( $(do_facet $facet lctl get_param $stats |
18666                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18667                         do_facet $facet lctl get_param $stats
18668                         error "No jobstats for $JOBVAL found on $facet::$stats"
18669                 fi
18670         done
18671 }
18672
18673 jobstats_set() {
18674         local new_jobenv=$1
18675
18676         set_persistent_param_and_check client "jobid_var" \
18677                 "$FSNAME.sys.jobid_var" $new_jobenv
18678 }
18679
18680 test_205a() { # Job stats
18681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18682         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18683                 skip "Need MDS version with at least 2.7.1"
18684         remote_mgs_nodsh && skip "remote MGS with nodsh"
18685         remote_mds_nodsh && skip "remote MDS with nodsh"
18686         remote_ost_nodsh && skip "remote OST with nodsh"
18687         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18688                 skip "Server doesn't support jobstats"
18689         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18690
18691         local old_jobenv=$($LCTL get_param -n jobid_var)
18692         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18693
18694         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18695                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18696         else
18697                 stack_trap "do_facet mgs $PERM_CMD \
18698                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18699         fi
18700         changelog_register
18701
18702         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18703                                 mdt.*.job_cleanup_interval | head -n 1)
18704         local new_interval=5
18705         do_facet $SINGLEMDS \
18706                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18707         stack_trap "do_facet $SINGLEMDS \
18708                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18709         local start=$SECONDS
18710
18711         local cmd
18712         # mkdir
18713         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18714         verify_jobstats "$cmd" "$SINGLEMDS"
18715         # rmdir
18716         cmd="rmdir $DIR/$tdir"
18717         verify_jobstats "$cmd" "$SINGLEMDS"
18718         # mkdir on secondary MDT
18719         if [ $MDSCOUNT -gt 1 ]; then
18720                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18721                 verify_jobstats "$cmd" "mds2"
18722         fi
18723         # mknod
18724         cmd="mknod $DIR/$tfile c 1 3"
18725         verify_jobstats "$cmd" "$SINGLEMDS"
18726         # unlink
18727         cmd="rm -f $DIR/$tfile"
18728         verify_jobstats "$cmd" "$SINGLEMDS"
18729         # create all files on OST0000 so verify_jobstats can find OST stats
18730         # open & close
18731         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18732         verify_jobstats "$cmd" "$SINGLEMDS"
18733         # setattr
18734         cmd="touch $DIR/$tfile"
18735         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18736         # write
18737         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18738         verify_jobstats "$cmd" "ost1"
18739         # read
18740         cancel_lru_locks osc
18741         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18742         verify_jobstats "$cmd" "ost1"
18743         # truncate
18744         cmd="$TRUNCATE $DIR/$tfile 0"
18745         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18746         # rename
18747         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18748         verify_jobstats "$cmd" "$SINGLEMDS"
18749         # jobstats expiry - sleep until old stats should be expired
18750         local left=$((new_interval + 5 - (SECONDS - start)))
18751         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18752                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18753                         "0" $left
18754         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18755         verify_jobstats "$cmd" "$SINGLEMDS"
18756         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18757             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18758
18759         # Ensure that jobid are present in changelog (if supported by MDS)
18760         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18761                 changelog_dump | tail -10
18762                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18763                 [ $jobids -eq 9 ] ||
18764                         error "Wrong changelog jobid count $jobids != 9"
18765
18766                 # LU-5862
18767                 JOBENV="disable"
18768                 jobstats_set $JOBENV
18769                 touch $DIR/$tfile
18770                 changelog_dump | grep $tfile
18771                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18772                 [ $jobids -eq 0 ] ||
18773                         error "Unexpected jobids when jobid_var=$JOBENV"
18774         fi
18775
18776         # test '%j' access to environment variable - if supported
18777         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18778                 JOBENV="JOBCOMPLEX"
18779                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18780
18781                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18782         fi
18783
18784         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18785                 JOBENV="JOBCOMPLEX"
18786                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18787
18788                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18789         fi
18790
18791         # test '%j' access to per-session jobid - if supported
18792         if lctl list_param jobid_this_session > /dev/null 2>&1
18793         then
18794                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18795                 lctl set_param jobid_this_session=$USER
18796
18797                 JOBENV="JOBCOMPLEX"
18798                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18799
18800                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18801         fi
18802 }
18803 run_test 205a "Verify job stats"
18804
18805 # LU-13117, LU-13597
18806 test_205b() {
18807         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18808                 skip "Need MDS version at least 2.13.54.91"
18809
18810         job_stats="mdt.*.job_stats"
18811         $LCTL set_param $job_stats=clear
18812         # Setting jobid_var to USER might not be supported
18813         $LCTL set_param jobid_var=USER || true
18814         $LCTL set_param jobid_name="%e.%u"
18815         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18816         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18817                 grep "job_id:.*foolish" &&
18818                         error "Unexpected jobid found"
18819         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18820                 grep "open:.*min.*max.*sum" ||
18821                         error "wrong job_stats format found"
18822 }
18823 run_test 205b "Verify job stats jobid and output format"
18824
18825 # LU-13733
18826 test_205c() {
18827         $LCTL set_param llite.*.stats=0
18828         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18829         $LCTL get_param llite.*.stats
18830         $LCTL get_param llite.*.stats | grep \
18831                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18832                         error "wrong client stats format found"
18833 }
18834 run_test 205c "Verify client stats format"
18835
18836 # LU-1480, LU-1773 and LU-1657
18837 test_206() {
18838         mkdir -p $DIR/$tdir
18839         $LFS setstripe -c -1 $DIR/$tdir
18840 #define OBD_FAIL_LOV_INIT 0x1403
18841         $LCTL set_param fail_loc=0xa0001403
18842         $LCTL set_param fail_val=1
18843         touch $DIR/$tdir/$tfile || true
18844 }
18845 run_test 206 "fail lov_init_raid0() doesn't lbug"
18846
18847 test_207a() {
18848         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18849         local fsz=`stat -c %s $DIR/$tfile`
18850         cancel_lru_locks mdc
18851
18852         # do not return layout in getattr intent
18853 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18854         $LCTL set_param fail_loc=0x170
18855         local sz=`stat -c %s $DIR/$tfile`
18856
18857         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18858
18859         rm -rf $DIR/$tfile
18860 }
18861 run_test 207a "can refresh layout at glimpse"
18862
18863 test_207b() {
18864         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18865         local cksum=`md5sum $DIR/$tfile`
18866         local fsz=`stat -c %s $DIR/$tfile`
18867         cancel_lru_locks mdc
18868         cancel_lru_locks osc
18869
18870         # do not return layout in getattr intent
18871 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18872         $LCTL set_param fail_loc=0x171
18873
18874         # it will refresh layout after the file is opened but before read issues
18875         echo checksum is "$cksum"
18876         echo "$cksum" |md5sum -c --quiet || error "file differs"
18877
18878         rm -rf $DIR/$tfile
18879 }
18880 run_test 207b "can refresh layout at open"
18881
18882 test_208() {
18883         # FIXME: in this test suite, only RD lease is used. This is okay
18884         # for now as only exclusive open is supported. After generic lease
18885         # is done, this test suite should be revised. - Jinshan
18886
18887         remote_mds_nodsh && skip "remote MDS with nodsh"
18888         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18889                 skip "Need MDS version at least 2.4.52"
18890
18891         echo "==== test 1: verify get lease work"
18892         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18893
18894         echo "==== test 2: verify lease can be broken by upcoming open"
18895         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18896         local PID=$!
18897         sleep 2
18898
18899         $MULTIOP $DIR/$tfile oO_RDWR:c
18900         kill -USR1 $PID && wait $PID || error "break lease error"
18901
18902         echo "==== test 3: verify lease can't be granted if an open already exists"
18903         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18904         local PID=$!
18905         sleep 2
18906
18907         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18908         kill -USR1 $PID && wait $PID || error "open file error"
18909
18910         echo "==== test 4: lease can sustain over recovery"
18911         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18912         PID=$!
18913         sleep 2
18914
18915         fail mds1
18916
18917         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18918
18919         echo "==== test 5: lease broken can't be regained by replay"
18920         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18921         PID=$!
18922         sleep 2
18923
18924         # open file to break lease and then recovery
18925         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18926         fail mds1
18927
18928         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18929
18930         rm -f $DIR/$tfile
18931 }
18932 run_test 208 "Exclusive open"
18933
18934 test_209() {
18935         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18936                 skip_env "must have disp_stripe"
18937
18938         touch $DIR/$tfile
18939         sync; sleep 5; sync;
18940
18941         echo 3 > /proc/sys/vm/drop_caches
18942         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18943                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18944         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18945
18946         # open/close 500 times
18947         for i in $(seq 500); do
18948                 cat $DIR/$tfile
18949         done
18950
18951         echo 3 > /proc/sys/vm/drop_caches
18952         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18953                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18954         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18955
18956         echo "before: $req_before, after: $req_after"
18957         [ $((req_after - req_before)) -ge 300 ] &&
18958                 error "open/close requests are not freed"
18959         return 0
18960 }
18961 run_test 209 "read-only open/close requests should be freed promptly"
18962
18963 test_210() {
18964         local pid
18965
18966         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18967         pid=$!
18968         sleep 1
18969
18970         $LFS getstripe $DIR/$tfile
18971         kill -USR1 $pid
18972         wait $pid || error "multiop failed"
18973
18974         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18975         pid=$!
18976         sleep 1
18977
18978         $LFS getstripe $DIR/$tfile
18979         kill -USR1 $pid
18980         wait $pid || error "multiop failed"
18981 }
18982 run_test 210 "lfs getstripe does not break leases"
18983
18984 test_212() {
18985         size=`date +%s`
18986         size=$((size % 8192 + 1))
18987         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18988         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18989         rm -f $DIR/f212 $DIR/f212.xyz
18990 }
18991 run_test 212 "Sendfile test ============================================"
18992
18993 test_213() {
18994         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18995         cancel_lru_locks osc
18996         lctl set_param fail_loc=0x8000040f
18997         # generate a read lock
18998         cat $DIR/$tfile > /dev/null
18999         # write to the file, it will try to cancel the above read lock.
19000         cat /etc/hosts >> $DIR/$tfile
19001 }
19002 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19003
19004 test_214() { # for bug 20133
19005         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19006         for (( i=0; i < 340; i++ )) ; do
19007                 touch $DIR/$tdir/d214c/a$i
19008         done
19009
19010         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19011         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19012         ls $DIR/d214c || error "ls $DIR/d214c failed"
19013         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19014         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19015 }
19016 run_test 214 "hash-indexed directory test - bug 20133"
19017
19018 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19019 create_lnet_proc_files() {
19020         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19021 }
19022
19023 # counterpart of create_lnet_proc_files
19024 remove_lnet_proc_files() {
19025         rm -f $TMP/lnet_$1.sys
19026 }
19027
19028 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19029 # 3rd arg as regexp for body
19030 check_lnet_proc_stats() {
19031         local l=$(cat "$TMP/lnet_$1" |wc -l)
19032         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19033
19034         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19035 }
19036
19037 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19038 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19039 # optional and can be regexp for 2nd line (lnet.routes case)
19040 check_lnet_proc_entry() {
19041         local blp=2          # blp stands for 'position of 1st line of body'
19042         [ -z "$5" ] || blp=3 # lnet.routes case
19043
19044         local l=$(cat "$TMP/lnet_$1" |wc -l)
19045         # subtracting one from $blp because the body can be empty
19046         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19047
19048         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19049                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19050
19051         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19052                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19053
19054         # bail out if any unexpected line happened
19055         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19056         [ "$?" != 0 ] || error "$2 misformatted"
19057 }
19058
19059 test_215() { # for bugs 18102, 21079, 21517
19060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19061
19062         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19063         local P='[1-9][0-9]*'           # positive numeric
19064         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19065         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19066         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19067         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19068
19069         local L1 # regexp for 1st line
19070         local L2 # regexp for 2nd line (optional)
19071         local BR # regexp for the rest (body)
19072
19073         # lnet.stats should look as 11 space-separated non-negative numerics
19074         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19075         create_lnet_proc_files "stats"
19076         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19077         remove_lnet_proc_files "stats"
19078
19079         # lnet.routes should look like this:
19080         # Routing disabled/enabled
19081         # net hops priority state router
19082         # where net is a string like tcp0, hops > 0, priority >= 0,
19083         # state is up/down,
19084         # router is a string like 192.168.1.1@tcp2
19085         L1="^Routing (disabled|enabled)$"
19086         L2="^net +hops +priority +state +router$"
19087         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19088         create_lnet_proc_files "routes"
19089         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19090         remove_lnet_proc_files "routes"
19091
19092         # lnet.routers should look like this:
19093         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19094         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19095         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19096         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19097         L1="^ref +rtr_ref +alive +router$"
19098         BR="^$P +$P +(up|down) +$NID$"
19099         create_lnet_proc_files "routers"
19100         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19101         remove_lnet_proc_files "routers"
19102
19103         # lnet.peers should look like this:
19104         # nid refs state last max rtr min tx min queue
19105         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19106         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19107         # numeric (0 or >0 or <0), queue >= 0.
19108         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19109         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19110         create_lnet_proc_files "peers"
19111         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19112         remove_lnet_proc_files "peers"
19113
19114         # lnet.buffers  should look like this:
19115         # pages count credits min
19116         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19117         L1="^pages +count +credits +min$"
19118         BR="^ +$N +$N +$I +$I$"
19119         create_lnet_proc_files "buffers"
19120         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19121         remove_lnet_proc_files "buffers"
19122
19123         # lnet.nis should look like this:
19124         # nid status alive refs peer rtr max tx min
19125         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19126         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19127         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19128         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19129         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19130         create_lnet_proc_files "nis"
19131         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19132         remove_lnet_proc_files "nis"
19133
19134         # can we successfully write to lnet.stats?
19135         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19136 }
19137 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19138
19139 test_216() { # bug 20317
19140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19141         remote_ost_nodsh && skip "remote OST with nodsh"
19142
19143         local node
19144         local facets=$(get_facets OST)
19145         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19146
19147         save_lustre_params client "osc.*.contention_seconds" > $p
19148         save_lustre_params $facets \
19149                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19150         save_lustre_params $facets \
19151                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19152         save_lustre_params $facets \
19153                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19154         clear_stats osc.*.osc_stats
19155
19156         # agressive lockless i/o settings
19157         do_nodes $(comma_list $(osts_nodes)) \
19158                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19159                         ldlm.namespaces.filter-*.contended_locks=0 \
19160                         ldlm.namespaces.filter-*.contention_seconds=60"
19161         lctl set_param -n osc.*.contention_seconds=60
19162
19163         $DIRECTIO write $DIR/$tfile 0 10 4096
19164         $CHECKSTAT -s 40960 $DIR/$tfile
19165
19166         # disable lockless i/o
19167         do_nodes $(comma_list $(osts_nodes)) \
19168                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19169                         ldlm.namespaces.filter-*.contended_locks=32 \
19170                         ldlm.namespaces.filter-*.contention_seconds=0"
19171         lctl set_param -n osc.*.contention_seconds=0
19172         clear_stats osc.*.osc_stats
19173
19174         dd if=/dev/zero of=$DIR/$tfile count=0
19175         $CHECKSTAT -s 0 $DIR/$tfile
19176
19177         restore_lustre_params <$p
19178         rm -f $p
19179         rm $DIR/$tfile
19180 }
19181 run_test 216 "check lockless direct write updates file size and kms correctly"
19182
19183 test_217() { # bug 22430
19184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19185
19186         local node
19187         local nid
19188
19189         for node in $(nodes_list); do
19190                 nid=$(host_nids_address $node $NETTYPE)
19191                 if [[ $nid = *-* ]] ; then
19192                         echo "lctl ping $(h2nettype $nid)"
19193                         lctl ping $(h2nettype $nid)
19194                 else
19195                         echo "skipping $node (no hyphen detected)"
19196                 fi
19197         done
19198 }
19199 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19200
19201 test_218() {
19202        # do directio so as not to populate the page cache
19203        log "creating a 10 Mb file"
19204        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19205        log "starting reads"
19206        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19207        log "truncating the file"
19208        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19209        log "killing dd"
19210        kill %+ || true # reads might have finished
19211        echo "wait until dd is finished"
19212        wait
19213        log "removing the temporary file"
19214        rm -rf $DIR/$tfile || error "tmp file removal failed"
19215 }
19216 run_test 218 "parallel read and truncate should not deadlock"
19217
19218 test_219() {
19219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19220
19221         # write one partial page
19222         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19223         # set no grant so vvp_io_commit_write will do sync write
19224         $LCTL set_param fail_loc=0x411
19225         # write a full page at the end of file
19226         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19227
19228         $LCTL set_param fail_loc=0
19229         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19230         $LCTL set_param fail_loc=0x411
19231         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19232
19233         # LU-4201
19234         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19235         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19236 }
19237 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19238
19239 test_220() { #LU-325
19240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19241         remote_ost_nodsh && skip "remote OST with nodsh"
19242         remote_mds_nodsh && skip "remote MDS with nodsh"
19243         remote_mgs_nodsh && skip "remote MGS with nodsh"
19244
19245         local OSTIDX=0
19246
19247         # create on MDT0000 so the last_id and next_id are correct
19248         mkdir_on_mdt0 $DIR/$tdir
19249         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19250         OST=${OST%_UUID}
19251
19252         # on the mdt's osc
19253         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19254         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19255                         osp.$mdtosc_proc1.prealloc_last_id)
19256         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19257                         osp.$mdtosc_proc1.prealloc_next_id)
19258
19259         $LFS df -i
19260
19261         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19262         #define OBD_FAIL_OST_ENOINO              0x229
19263         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19264         create_pool $FSNAME.$TESTNAME || return 1
19265         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19266
19267         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19268
19269         MDSOBJS=$((last_id - next_id))
19270         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19271
19272         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19273         echo "OST still has $count kbytes free"
19274
19275         echo "create $MDSOBJS files @next_id..."
19276         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19277
19278         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19279                         osp.$mdtosc_proc1.prealloc_last_id)
19280         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19281                         osp.$mdtosc_proc1.prealloc_next_id)
19282
19283         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19284         $LFS df -i
19285
19286         echo "cleanup..."
19287
19288         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19289         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19290
19291         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19292                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19293         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19294                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19295         echo "unlink $MDSOBJS files @$next_id..."
19296         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19297 }
19298 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19299
19300 test_221() {
19301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19302
19303         dd if=`which date` of=$MOUNT/date oflag=sync
19304         chmod +x $MOUNT/date
19305
19306         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19307         $LCTL set_param fail_loc=0x80001401
19308
19309         $MOUNT/date > /dev/null
19310         rm -f $MOUNT/date
19311 }
19312 run_test 221 "make sure fault and truncate race to not cause OOM"
19313
19314 test_222a () {
19315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19316
19317         rm -rf $DIR/$tdir
19318         test_mkdir $DIR/$tdir
19319         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19320         createmany -o $DIR/$tdir/$tfile 10
19321         cancel_lru_locks mdc
19322         cancel_lru_locks osc
19323         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19324         $LCTL set_param fail_loc=0x31a
19325         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19326         $LCTL set_param fail_loc=0
19327         rm -r $DIR/$tdir
19328 }
19329 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19330
19331 test_222b () {
19332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19333
19334         rm -rf $DIR/$tdir
19335         test_mkdir $DIR/$tdir
19336         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19337         createmany -o $DIR/$tdir/$tfile 10
19338         cancel_lru_locks mdc
19339         cancel_lru_locks osc
19340         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19341         $LCTL set_param fail_loc=0x31a
19342         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19343         $LCTL set_param fail_loc=0
19344 }
19345 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19346
19347 test_223 () {
19348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19349
19350         rm -rf $DIR/$tdir
19351         test_mkdir $DIR/$tdir
19352         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19353         createmany -o $DIR/$tdir/$tfile 10
19354         cancel_lru_locks mdc
19355         cancel_lru_locks osc
19356         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19357         $LCTL set_param fail_loc=0x31b
19358         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19359         $LCTL set_param fail_loc=0
19360         rm -r $DIR/$tdir
19361 }
19362 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19363
19364 test_224a() { # LU-1039, MRP-303
19365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19366         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19367         $LCTL set_param fail_loc=0x508
19368         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19369         $LCTL set_param fail_loc=0
19370         df $DIR
19371 }
19372 run_test 224a "Don't panic on bulk IO failure"
19373
19374 test_224bd_sub() { # LU-1039, MRP-303
19375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19376         local timeout=$1
19377
19378         shift
19379         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19380
19381         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19382
19383         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19384         cancel_lru_locks osc
19385         set_checksums 0
19386         stack_trap "set_checksums $ORIG_CSUM" EXIT
19387         local at_max_saved=0
19388
19389         # adaptive timeouts may prevent seeing the issue
19390         if at_is_enabled; then
19391                 at_max_saved=$(at_max_get mds)
19392                 at_max_set 0 mds client
19393                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19394         fi
19395
19396         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19397         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19398         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19399
19400         do_facet ost1 $LCTL set_param fail_loc=0
19401         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19402         df $DIR
19403 }
19404
19405 test_224b() {
19406         test_224bd_sub 3 error "dd failed"
19407 }
19408 run_test 224b "Don't panic on bulk IO failure"
19409
19410 test_224c() { # LU-6441
19411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19412         remote_mds_nodsh && skip "remote MDS with nodsh"
19413
19414         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19415         save_writethrough $p
19416         set_cache writethrough on
19417
19418         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19419         local at_max=$($LCTL get_param -n at_max)
19420         local timeout=$($LCTL get_param -n timeout)
19421         local test_at="at_max"
19422         local param_at="$FSNAME.sys.at_max"
19423         local test_timeout="timeout"
19424         local param_timeout="$FSNAME.sys.timeout"
19425
19426         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19427
19428         set_persistent_param_and_check client "$test_at" "$param_at" 0
19429         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19430
19431         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19432         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19433         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19434         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19435         sync
19436         do_facet ost1 "$LCTL set_param fail_loc=0"
19437
19438         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19439         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19440                 $timeout
19441
19442         $LCTL set_param -n $pages_per_rpc
19443         restore_lustre_params < $p
19444         rm -f $p
19445 }
19446 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19447
19448 test_224d() { # LU-11169
19449         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19450 }
19451 run_test 224d "Don't corrupt data on bulk IO timeout"
19452
19453 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19454 test_225a () {
19455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19456         if [ -z ${MDSSURVEY} ]; then
19457                 skip_env "mds-survey not found"
19458         fi
19459         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19460                 skip "Need MDS version at least 2.2.51"
19461
19462         local mds=$(facet_host $SINGLEMDS)
19463         local target=$(do_nodes $mds 'lctl dl' |
19464                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19465
19466         local cmd1="file_count=1000 thrhi=4"
19467         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19468         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19469         local cmd="$cmd1 $cmd2 $cmd3"
19470
19471         rm -f ${TMP}/mds_survey*
19472         echo + $cmd
19473         eval $cmd || error "mds-survey with zero-stripe failed"
19474         cat ${TMP}/mds_survey*
19475         rm -f ${TMP}/mds_survey*
19476 }
19477 run_test 225a "Metadata survey sanity with zero-stripe"
19478
19479 test_225b () {
19480         if [ -z ${MDSSURVEY} ]; then
19481                 skip_env "mds-survey not found"
19482         fi
19483         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19484                 skip "Need MDS version at least 2.2.51"
19485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19486         remote_mds_nodsh && skip "remote MDS with nodsh"
19487         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19488                 skip_env "Need to mount OST to test"
19489         fi
19490
19491         local mds=$(facet_host $SINGLEMDS)
19492         local target=$(do_nodes $mds 'lctl dl' |
19493                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19494
19495         local cmd1="file_count=1000 thrhi=4"
19496         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19497         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19498         local cmd="$cmd1 $cmd2 $cmd3"
19499
19500         rm -f ${TMP}/mds_survey*
19501         echo + $cmd
19502         eval $cmd || error "mds-survey with stripe_count failed"
19503         cat ${TMP}/mds_survey*
19504         rm -f ${TMP}/mds_survey*
19505 }
19506 run_test 225b "Metadata survey sanity with stripe_count = 1"
19507
19508 mcreate_path2fid () {
19509         local mode=$1
19510         local major=$2
19511         local minor=$3
19512         local name=$4
19513         local desc=$5
19514         local path=$DIR/$tdir/$name
19515         local fid
19516         local rc
19517         local fid_path
19518
19519         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19520                 error "cannot create $desc"
19521
19522         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19523         rc=$?
19524         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19525
19526         fid_path=$($LFS fid2path $MOUNT $fid)
19527         rc=$?
19528         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19529
19530         [ "$path" == "$fid_path" ] ||
19531                 error "fid2path returned $fid_path, expected $path"
19532
19533         echo "pass with $path and $fid"
19534 }
19535
19536 test_226a () {
19537         rm -rf $DIR/$tdir
19538         mkdir -p $DIR/$tdir
19539
19540         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19541         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19542         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19543         mcreate_path2fid 0040666 0 0 dir "directory"
19544         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19545         mcreate_path2fid 0100666 0 0 file "regular file"
19546         mcreate_path2fid 0120666 0 0 link "symbolic link"
19547         mcreate_path2fid 0140666 0 0 sock "socket"
19548 }
19549 run_test 226a "call path2fid and fid2path on files of all type"
19550
19551 test_226b () {
19552         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19553
19554         local MDTIDX=1
19555
19556         rm -rf $DIR/$tdir
19557         mkdir -p $DIR/$tdir
19558         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19559                 error "create remote directory failed"
19560         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19561         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19562                                 "character special file (null)"
19563         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19564                                 "character special file (no device)"
19565         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19566         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19567                                 "block special file (loop)"
19568         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19569         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19570         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19571 }
19572 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19573
19574 test_226c () {
19575         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19576         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19577                 skip "Need MDS version at least 2.13.55"
19578
19579         local submnt=/mnt/submnt
19580         local srcfile=/etc/passwd
19581         local dstfile=$submnt/passwd
19582         local path
19583         local fid
19584
19585         rm -rf $DIR/$tdir
19586         rm -rf $submnt
19587         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19588                 error "create remote directory failed"
19589         mkdir -p $submnt || error "create $submnt failed"
19590         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19591                 error "mount $submnt failed"
19592         stack_trap "umount $submnt" EXIT
19593
19594         cp $srcfile $dstfile
19595         fid=$($LFS path2fid $dstfile)
19596         path=$($LFS fid2path $submnt "$fid")
19597         [ "$path" = "$dstfile" ] ||
19598                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19599 }
19600 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19601
19602 # LU-1299 Executing or running ldd on a truncated executable does not
19603 # cause an out-of-memory condition.
19604 test_227() {
19605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19606         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19607
19608         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19609         chmod +x $MOUNT/date
19610
19611         $MOUNT/date > /dev/null
19612         ldd $MOUNT/date > /dev/null
19613         rm -f $MOUNT/date
19614 }
19615 run_test 227 "running truncated executable does not cause OOM"
19616
19617 # LU-1512 try to reuse idle OI blocks
19618 test_228a() {
19619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19620         remote_mds_nodsh && skip "remote MDS with nodsh"
19621         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19622
19623         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19624         local myDIR=$DIR/$tdir
19625
19626         mkdir -p $myDIR
19627         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19628         $LCTL set_param fail_loc=0x80001002
19629         createmany -o $myDIR/t- 10000
19630         $LCTL set_param fail_loc=0
19631         # The guard is current the largest FID holder
19632         touch $myDIR/guard
19633         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19634                     tr -d '[')
19635         local IDX=$(($SEQ % 64))
19636
19637         do_facet $SINGLEMDS sync
19638         # Make sure journal flushed.
19639         sleep 6
19640         local blk1=$(do_facet $SINGLEMDS \
19641                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19642                      grep Blockcount | awk '{print $4}')
19643
19644         # Remove old files, some OI blocks will become idle.
19645         unlinkmany $myDIR/t- 10000
19646         # Create new files, idle OI blocks should be reused.
19647         createmany -o $myDIR/t- 2000
19648         do_facet $SINGLEMDS sync
19649         # Make sure journal flushed.
19650         sleep 6
19651         local blk2=$(do_facet $SINGLEMDS \
19652                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19653                      grep Blockcount | awk '{print $4}')
19654
19655         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19656 }
19657 run_test 228a "try to reuse idle OI blocks"
19658
19659 test_228b() {
19660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19661         remote_mds_nodsh && skip "remote MDS with nodsh"
19662         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19663
19664         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19665         local myDIR=$DIR/$tdir
19666
19667         mkdir -p $myDIR
19668         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19669         $LCTL set_param fail_loc=0x80001002
19670         createmany -o $myDIR/t- 10000
19671         $LCTL set_param fail_loc=0
19672         # The guard is current the largest FID holder
19673         touch $myDIR/guard
19674         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19675                     tr -d '[')
19676         local IDX=$(($SEQ % 64))
19677
19678         do_facet $SINGLEMDS sync
19679         # Make sure journal flushed.
19680         sleep 6
19681         local blk1=$(do_facet $SINGLEMDS \
19682                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19683                      grep Blockcount | awk '{print $4}')
19684
19685         # Remove old files, some OI blocks will become idle.
19686         unlinkmany $myDIR/t- 10000
19687
19688         # stop the MDT
19689         stop $SINGLEMDS || error "Fail to stop MDT."
19690         # remount the MDT
19691         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19692                 error "Fail to start MDT."
19693
19694         df $MOUNT || error "Fail to df."
19695         # Create new files, idle OI blocks should be reused.
19696         createmany -o $myDIR/t- 2000
19697         do_facet $SINGLEMDS sync
19698         # Make sure journal flushed.
19699         sleep 6
19700         local blk2=$(do_facet $SINGLEMDS \
19701                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19702                      grep Blockcount | awk '{print $4}')
19703
19704         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19705 }
19706 run_test 228b "idle OI blocks can be reused after MDT restart"
19707
19708 #LU-1881
19709 test_228c() {
19710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19711         remote_mds_nodsh && skip "remote MDS with nodsh"
19712         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19713
19714         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19715         local myDIR=$DIR/$tdir
19716
19717         mkdir -p $myDIR
19718         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19719         $LCTL set_param fail_loc=0x80001002
19720         # 20000 files can guarantee there are index nodes in the OI file
19721         createmany -o $myDIR/t- 20000
19722         $LCTL set_param fail_loc=0
19723         # The guard is current the largest FID holder
19724         touch $myDIR/guard
19725         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19726                     tr -d '[')
19727         local IDX=$(($SEQ % 64))
19728
19729         do_facet $SINGLEMDS sync
19730         # Make sure journal flushed.
19731         sleep 6
19732         local blk1=$(do_facet $SINGLEMDS \
19733                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19734                      grep Blockcount | awk '{print $4}')
19735
19736         # Remove old files, some OI blocks will become idle.
19737         unlinkmany $myDIR/t- 20000
19738         rm -f $myDIR/guard
19739         # The OI file should become empty now
19740
19741         # Create new files, idle OI blocks should be reused.
19742         createmany -o $myDIR/t- 2000
19743         do_facet $SINGLEMDS sync
19744         # Make sure journal flushed.
19745         sleep 6
19746         local blk2=$(do_facet $SINGLEMDS \
19747                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19748                      grep Blockcount | awk '{print $4}')
19749
19750         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19751 }
19752 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19753
19754 test_229() { # LU-2482, LU-3448
19755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19756         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19757         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19758                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19759
19760         rm -f $DIR/$tfile
19761
19762         # Create a file with a released layout and stripe count 2.
19763         $MULTIOP $DIR/$tfile H2c ||
19764                 error "failed to create file with released layout"
19765
19766         $LFS getstripe -v $DIR/$tfile
19767
19768         local pattern=$($LFS getstripe -L $DIR/$tfile)
19769         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19770
19771         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19772                 error "getstripe"
19773         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19774         stat $DIR/$tfile || error "failed to stat released file"
19775
19776         chown $RUNAS_ID $DIR/$tfile ||
19777                 error "chown $RUNAS_ID $DIR/$tfile failed"
19778
19779         chgrp $RUNAS_ID $DIR/$tfile ||
19780                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19781
19782         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19783         rm $DIR/$tfile || error "failed to remove released file"
19784 }
19785 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19786
19787 test_230a() {
19788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19790         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19791                 skip "Need MDS version at least 2.11.52"
19792
19793         local MDTIDX=1
19794
19795         test_mkdir $DIR/$tdir
19796         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19797         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19798         [ $mdt_idx -ne 0 ] &&
19799                 error "create local directory on wrong MDT $mdt_idx"
19800
19801         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19802                         error "create remote directory failed"
19803         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19804         [ $mdt_idx -ne $MDTIDX ] &&
19805                 error "create remote directory on wrong MDT $mdt_idx"
19806
19807         createmany -o $DIR/$tdir/test_230/t- 10 ||
19808                 error "create files on remote directory failed"
19809         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19810         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19811         rm -r $DIR/$tdir || error "unlink remote directory failed"
19812 }
19813 run_test 230a "Create remote directory and files under the remote directory"
19814
19815 test_230b() {
19816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19818         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19819                 skip "Need MDS version at least 2.11.52"
19820
19821         local MDTIDX=1
19822         local mdt_index
19823         local i
19824         local file
19825         local pid
19826         local stripe_count
19827         local migrate_dir=$DIR/$tdir/migrate_dir
19828         local other_dir=$DIR/$tdir/other_dir
19829
19830         test_mkdir $DIR/$tdir
19831         test_mkdir -i0 -c1 $migrate_dir
19832         test_mkdir -i0 -c1 $other_dir
19833         for ((i=0; i<10; i++)); do
19834                 mkdir -p $migrate_dir/dir_${i}
19835                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19836                         error "create files under remote dir failed $i"
19837         done
19838
19839         cp /etc/passwd $migrate_dir/$tfile
19840         cp /etc/passwd $other_dir/$tfile
19841         chattr +SAD $migrate_dir
19842         chattr +SAD $migrate_dir/$tfile
19843
19844         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19845         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19846         local old_dir_mode=$(stat -c%f $migrate_dir)
19847         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19848
19849         mkdir -p $migrate_dir/dir_default_stripe2
19850         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19851         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19852
19853         mkdir -p $other_dir
19854         ln $migrate_dir/$tfile $other_dir/luna
19855         ln $migrate_dir/$tfile $migrate_dir/sofia
19856         ln $other_dir/$tfile $migrate_dir/david
19857         ln -s $migrate_dir/$tfile $other_dir/zachary
19858         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19859         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19860
19861         local len
19862         local lnktgt
19863
19864         # inline symlink
19865         for len in 58 59 60; do
19866                 lnktgt=$(str_repeat 'l' $len)
19867                 touch $migrate_dir/$lnktgt
19868                 ln -s $lnktgt $migrate_dir/${len}char_ln
19869         done
19870
19871         # PATH_MAX
19872         for len in 4094 4095; do
19873                 lnktgt=$(str_repeat 'l' $len)
19874                 ln -s $lnktgt $migrate_dir/${len}char_ln
19875         done
19876
19877         # NAME_MAX
19878         for len in 254 255; do
19879                 touch $migrate_dir/$(str_repeat 'l' $len)
19880         done
19881
19882         $LFS migrate -m $MDTIDX $migrate_dir ||
19883                 error "fails on migrating remote dir to MDT1"
19884
19885         echo "migratate to MDT1, then checking.."
19886         for ((i = 0; i < 10; i++)); do
19887                 for file in $(find $migrate_dir/dir_${i}); do
19888                         mdt_index=$($LFS getstripe -m $file)
19889                         # broken symlink getstripe will fail
19890                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19891                                 error "$file is not on MDT${MDTIDX}"
19892                 done
19893         done
19894
19895         # the multiple link file should still in MDT0
19896         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19897         [ $mdt_index == 0 ] ||
19898                 error "$file is not on MDT${MDTIDX}"
19899
19900         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19901         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19902                 error " expect $old_dir_flag get $new_dir_flag"
19903
19904         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19905         [ "$old_file_flag" = "$new_file_flag" ] ||
19906                 error " expect $old_file_flag get $new_file_flag"
19907
19908         local new_dir_mode=$(stat -c%f $migrate_dir)
19909         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19910                 error "expect mode $old_dir_mode get $new_dir_mode"
19911
19912         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19913         [ "$old_file_mode" = "$new_file_mode" ] ||
19914                 error "expect mode $old_file_mode get $new_file_mode"
19915
19916         diff /etc/passwd $migrate_dir/$tfile ||
19917                 error "$tfile different after migration"
19918
19919         diff /etc/passwd $other_dir/luna ||
19920                 error "luna different after migration"
19921
19922         diff /etc/passwd $migrate_dir/sofia ||
19923                 error "sofia different after migration"
19924
19925         diff /etc/passwd $migrate_dir/david ||
19926                 error "david different after migration"
19927
19928         diff /etc/passwd $other_dir/zachary ||
19929                 error "zachary different after migration"
19930
19931         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19932                 error "${tfile}_ln different after migration"
19933
19934         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19935                 error "${tfile}_ln_other different after migration"
19936
19937         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19938         [ $stripe_count = 2 ] ||
19939                 error "dir strpe_count $d != 2 after migration."
19940
19941         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19942         [ $stripe_count = 2 ] ||
19943                 error "file strpe_count $d != 2 after migration."
19944
19945         #migrate back to MDT0
19946         MDTIDX=0
19947
19948         $LFS migrate -m $MDTIDX $migrate_dir ||
19949                 error "fails on migrating remote dir to MDT0"
19950
19951         echo "migrate back to MDT0, checking.."
19952         for file in $(find $migrate_dir); do
19953                 mdt_index=$($LFS getstripe -m $file)
19954                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19955                         error "$file is not on MDT${MDTIDX}"
19956         done
19957
19958         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19959         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19960                 error " expect $old_dir_flag get $new_dir_flag"
19961
19962         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19963         [ "$old_file_flag" = "$new_file_flag" ] ||
19964                 error " expect $old_file_flag get $new_file_flag"
19965
19966         local new_dir_mode=$(stat -c%f $migrate_dir)
19967         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19968                 error "expect mode $old_dir_mode get $new_dir_mode"
19969
19970         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19971         [ "$old_file_mode" = "$new_file_mode" ] ||
19972                 error "expect mode $old_file_mode get $new_file_mode"
19973
19974         diff /etc/passwd ${migrate_dir}/$tfile ||
19975                 error "$tfile different after migration"
19976
19977         diff /etc/passwd ${other_dir}/luna ||
19978                 error "luna different after migration"
19979
19980         diff /etc/passwd ${migrate_dir}/sofia ||
19981                 error "sofia different after migration"
19982
19983         diff /etc/passwd ${other_dir}/zachary ||
19984                 error "zachary different after migration"
19985
19986         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19987                 error "${tfile}_ln different after migration"
19988
19989         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19990                 error "${tfile}_ln_other different after migration"
19991
19992         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19993         [ $stripe_count = 2 ] ||
19994                 error "dir strpe_count $d != 2 after migration."
19995
19996         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19997         [ $stripe_count = 2 ] ||
19998                 error "file strpe_count $d != 2 after migration."
19999
20000         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20001 }
20002 run_test 230b "migrate directory"
20003
20004 test_230c() {
20005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20006         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20007         remote_mds_nodsh && skip "remote MDS with nodsh"
20008         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20009                 skip "Need MDS version at least 2.11.52"
20010
20011         local MDTIDX=1
20012         local total=3
20013         local mdt_index
20014         local file
20015         local migrate_dir=$DIR/$tdir/migrate_dir
20016
20017         #If migrating directory fails in the middle, all entries of
20018         #the directory is still accessiable.
20019         test_mkdir $DIR/$tdir
20020         test_mkdir -i0 -c1 $migrate_dir
20021         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20022         stat $migrate_dir
20023         createmany -o $migrate_dir/f $total ||
20024                 error "create files under ${migrate_dir} failed"
20025
20026         # fail after migrating top dir, and this will fail only once, so the
20027         # first sub file migration will fail (currently f3), others succeed.
20028         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20029         do_facet mds1 lctl set_param fail_loc=0x1801
20030         local t=$(ls $migrate_dir | wc -l)
20031         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20032                 error "migrate should fail"
20033         local u=$(ls $migrate_dir | wc -l)
20034         [ "$u" == "$t" ] || error "$u != $t during migration"
20035
20036         # add new dir/file should succeed
20037         mkdir $migrate_dir/dir ||
20038                 error "mkdir failed under migrating directory"
20039         touch $migrate_dir/file ||
20040                 error "create file failed under migrating directory"
20041
20042         # add file with existing name should fail
20043         for file in $migrate_dir/f*; do
20044                 stat $file > /dev/null || error "stat $file failed"
20045                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20046                         error "open(O_CREAT|O_EXCL) $file should fail"
20047                 $MULTIOP $file m && error "create $file should fail"
20048                 touch $DIR/$tdir/remote_dir/$tfile ||
20049                         error "touch $tfile failed"
20050                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20051                         error "link $file should fail"
20052                 mdt_index=$($LFS getstripe -m $file)
20053                 if [ $mdt_index == 0 ]; then
20054                         # file failed to migrate is not allowed to rename to
20055                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20056                                 error "rename to $file should fail"
20057                 else
20058                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20059                                 error "rename to $file failed"
20060                 fi
20061                 echo hello >> $file || error "write $file failed"
20062         done
20063
20064         # resume migration with different options should fail
20065         $LFS migrate -m 0 $migrate_dir &&
20066                 error "migrate -m 0 $migrate_dir should fail"
20067
20068         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20069                 error "migrate -c 2 $migrate_dir should fail"
20070
20071         # resume migration should succeed
20072         $LFS migrate -m $MDTIDX $migrate_dir ||
20073                 error "migrate $migrate_dir failed"
20074
20075         echo "Finish migration, then checking.."
20076         for file in $(find $migrate_dir); do
20077                 mdt_index=$($LFS getstripe -m $file)
20078                 [ $mdt_index == $MDTIDX ] ||
20079                         error "$file is not on MDT${MDTIDX}"
20080         done
20081
20082         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20083 }
20084 run_test 230c "check directory accessiblity if migration failed"
20085
20086 test_230d() {
20087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20088         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20089         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20090                 skip "Need MDS version at least 2.11.52"
20091         # LU-11235
20092         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20093
20094         local migrate_dir=$DIR/$tdir/migrate_dir
20095         local old_index
20096         local new_index
20097         local old_count
20098         local new_count
20099         local new_hash
20100         local mdt_index
20101         local i
20102         local j
20103
20104         old_index=$((RANDOM % MDSCOUNT))
20105         old_count=$((MDSCOUNT - old_index))
20106         new_index=$((RANDOM % MDSCOUNT))
20107         new_count=$((MDSCOUNT - new_index))
20108         new_hash=1 # for all_char
20109
20110         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20111         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20112
20113         test_mkdir $DIR/$tdir
20114         test_mkdir -i $old_index -c $old_count $migrate_dir
20115
20116         for ((i=0; i<100; i++)); do
20117                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20118                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20119                         error "create files under remote dir failed $i"
20120         done
20121
20122         echo -n "Migrate from MDT$old_index "
20123         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20124         echo -n "to MDT$new_index"
20125         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20126         echo
20127
20128         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20129         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20130                 error "migrate remote dir error"
20131
20132         echo "Finish migration, then checking.."
20133         for file in $(find $migrate_dir -maxdepth 1); do
20134                 mdt_index=$($LFS getstripe -m $file)
20135                 if [ $mdt_index -lt $new_index ] ||
20136                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20137                         error "$file is on MDT$mdt_index"
20138                 fi
20139         done
20140
20141         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20142 }
20143 run_test 230d "check migrate big directory"
20144
20145 test_230e() {
20146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20148         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20149                 skip "Need MDS version at least 2.11.52"
20150
20151         local i
20152         local j
20153         local a_fid
20154         local b_fid
20155
20156         mkdir_on_mdt0 $DIR/$tdir
20157         mkdir $DIR/$tdir/migrate_dir
20158         mkdir $DIR/$tdir/other_dir
20159         touch $DIR/$tdir/migrate_dir/a
20160         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20161         ls $DIR/$tdir/other_dir
20162
20163         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20164                 error "migrate dir fails"
20165
20166         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20167         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20168
20169         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20170         [ $mdt_index == 0 ] || error "a is not on MDT0"
20171
20172         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20173                 error "migrate dir fails"
20174
20175         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20176         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20177
20178         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20179         [ $mdt_index == 1 ] || error "a is not on MDT1"
20180
20181         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20182         [ $mdt_index == 1 ] || error "b is not on MDT1"
20183
20184         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20185         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20186
20187         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20188
20189         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20190 }
20191 run_test 230e "migrate mulitple local link files"
20192
20193 test_230f() {
20194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20196         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20197                 skip "Need MDS version at least 2.11.52"
20198
20199         local a_fid
20200         local ln_fid
20201
20202         mkdir -p $DIR/$tdir
20203         mkdir $DIR/$tdir/migrate_dir
20204         $LFS mkdir -i1 $DIR/$tdir/other_dir
20205         touch $DIR/$tdir/migrate_dir/a
20206         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20207         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20208         ls $DIR/$tdir/other_dir
20209
20210         # a should be migrated to MDT1, since no other links on MDT0
20211         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20212                 error "#1 migrate dir fails"
20213         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20214         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20215         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20216         [ $mdt_index == 1 ] || error "a is not on MDT1"
20217
20218         # a should stay on MDT1, because it is a mulitple link file
20219         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20220                 error "#2 migrate dir fails"
20221         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20222         [ $mdt_index == 1 ] || error "a is not on MDT1"
20223
20224         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20225                 error "#3 migrate dir fails"
20226
20227         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20228         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20229         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20230
20231         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20232         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20233
20234         # a should be migrated to MDT0, since no other links on MDT1
20235         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20236                 error "#4 migrate dir fails"
20237         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20238         [ $mdt_index == 0 ] || error "a is not on MDT0"
20239
20240         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20241 }
20242 run_test 230f "migrate mulitple remote link files"
20243
20244 test_230g() {
20245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20246         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20247         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20248                 skip "Need MDS version at least 2.11.52"
20249
20250         mkdir -p $DIR/$tdir/migrate_dir
20251
20252         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20253                 error "migrating dir to non-exist MDT succeeds"
20254         true
20255 }
20256 run_test 230g "migrate dir to non-exist MDT"
20257
20258 test_230h() {
20259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20261         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20262                 skip "Need MDS version at least 2.11.52"
20263
20264         local mdt_index
20265
20266         mkdir -p $DIR/$tdir/migrate_dir
20267
20268         $LFS migrate -m1 $DIR &&
20269                 error "migrating mountpoint1 should fail"
20270
20271         $LFS migrate -m1 $DIR/$tdir/.. &&
20272                 error "migrating mountpoint2 should fail"
20273
20274         # same as mv
20275         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20276                 error "migrating $tdir/migrate_dir/.. should fail"
20277
20278         true
20279 }
20280 run_test 230h "migrate .. and root"
20281
20282 test_230i() {
20283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20284         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20285         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20286                 skip "Need MDS version at least 2.11.52"
20287
20288         mkdir -p $DIR/$tdir/migrate_dir
20289
20290         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20291                 error "migration fails with a tailing slash"
20292
20293         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20294                 error "migration fails with two tailing slashes"
20295 }
20296 run_test 230i "lfs migrate -m tolerates trailing slashes"
20297
20298 test_230j() {
20299         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20300         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20301                 skip "Need MDS version at least 2.11.52"
20302
20303         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20304         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20305                 error "create $tfile failed"
20306         cat /etc/passwd > $DIR/$tdir/$tfile
20307
20308         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20309
20310         cmp /etc/passwd $DIR/$tdir/$tfile ||
20311                 error "DoM file mismatch after migration"
20312 }
20313 run_test 230j "DoM file data not changed after dir migration"
20314
20315 test_230k() {
20316         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20317         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20318                 skip "Need MDS version at least 2.11.56"
20319
20320         local total=20
20321         local files_on_starting_mdt=0
20322
20323         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20324         $LFS getdirstripe $DIR/$tdir
20325         for i in $(seq $total); do
20326                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20327                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20328                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20329         done
20330
20331         echo "$files_on_starting_mdt files on MDT0"
20332
20333         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20334         $LFS getdirstripe $DIR/$tdir
20335
20336         files_on_starting_mdt=0
20337         for i in $(seq $total); do
20338                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20339                         error "file $tfile.$i mismatch after migration"
20340                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20341                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20342         done
20343
20344         echo "$files_on_starting_mdt files on MDT1 after migration"
20345         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20346
20347         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20348         $LFS getdirstripe $DIR/$tdir
20349
20350         files_on_starting_mdt=0
20351         for i in $(seq $total); do
20352                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20353                         error "file $tfile.$i mismatch after 2nd migration"
20354                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20355                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20356         done
20357
20358         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20359         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20360
20361         true
20362 }
20363 run_test 230k "file data not changed after dir migration"
20364
20365 test_230l() {
20366         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20367         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20368                 skip "Need MDS version at least 2.11.56"
20369
20370         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20371         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20372                 error "create files under remote dir failed $i"
20373         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20374 }
20375 run_test 230l "readdir between MDTs won't crash"
20376
20377 test_230m() {
20378         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20379         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20380                 skip "Need MDS version at least 2.11.56"
20381
20382         local MDTIDX=1
20383         local mig_dir=$DIR/$tdir/migrate_dir
20384         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20385         local shortstr="b"
20386         local val
20387
20388         echo "Creating files and dirs with xattrs"
20389         test_mkdir $DIR/$tdir
20390         test_mkdir -i0 -c1 $mig_dir
20391         mkdir $mig_dir/dir
20392         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20393                 error "cannot set xattr attr1 on dir"
20394         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20395                 error "cannot set xattr attr2 on dir"
20396         touch $mig_dir/dir/f0
20397         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20398                 error "cannot set xattr attr1 on file"
20399         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20400                 error "cannot set xattr attr2 on file"
20401         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20402         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20403         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20404         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20405         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20406         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20407         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20408         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20409         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20410
20411         echo "Migrating to MDT1"
20412         $LFS migrate -m $MDTIDX $mig_dir ||
20413                 error "fails on migrating dir to MDT1"
20414
20415         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20416         echo "Checking xattrs"
20417         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20418         [ "$val" = $longstr ] ||
20419                 error "expecting xattr1 $longstr on dir, found $val"
20420         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20421         [ "$val" = $shortstr ] ||
20422                 error "expecting xattr2 $shortstr on dir, found $val"
20423         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20424         [ "$val" = $longstr ] ||
20425                 error "expecting xattr1 $longstr on file, found $val"
20426         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20427         [ "$val" = $shortstr ] ||
20428                 error "expecting xattr2 $shortstr on file, found $val"
20429 }
20430 run_test 230m "xattrs not changed after dir migration"
20431
20432 test_230n() {
20433         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20434         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20435                 skip "Need MDS version at least 2.13.53"
20436
20437         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20438         cat /etc/hosts > $DIR/$tdir/$tfile
20439         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20440         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20441
20442         cmp /etc/hosts $DIR/$tdir/$tfile ||
20443                 error "File data mismatch after migration"
20444 }
20445 run_test 230n "Dir migration with mirrored file"
20446
20447 test_230o() {
20448         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20449         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20450                 skip "Need MDS version at least 2.13.52"
20451
20452         local mdts=$(comma_list $(mdts_nodes))
20453         local timeout=100
20454         local restripe_status
20455         local delta
20456         local i
20457
20458         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20459
20460         # in case "crush" hash type is not set
20461         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20462
20463         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20464                            mdt.*MDT0000.enable_dir_restripe)
20465         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20466         stack_trap "do_nodes $mdts $LCTL set_param \
20467                     mdt.*.enable_dir_restripe=$restripe_status"
20468
20469         mkdir $DIR/$tdir
20470         createmany -m $DIR/$tdir/f 100 ||
20471                 error "create files under remote dir failed $i"
20472         createmany -d $DIR/$tdir/d 100 ||
20473                 error "create dirs under remote dir failed $i"
20474
20475         for i in $(seq 2 $MDSCOUNT); do
20476                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20477                 $LFS setdirstripe -c $i $DIR/$tdir ||
20478                         error "split -c $i $tdir failed"
20479                 wait_update $HOSTNAME \
20480                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20481                         error "dir split not finished"
20482                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20483                         awk '/migrate/ {sum += $2} END { print sum }')
20484                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20485                 # delta is around total_files/stripe_count
20486                 (( $delta < 200 / (i - 1) + 4 )) ||
20487                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20488         done
20489 }
20490 run_test 230o "dir split"
20491
20492 test_230p() {
20493         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20494         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20495                 skip "Need MDS version at least 2.13.52"
20496
20497         local mdts=$(comma_list $(mdts_nodes))
20498         local timeout=100
20499         local restripe_status
20500         local delta
20501         local c
20502
20503         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20504
20505         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20506
20507         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20508                            mdt.*MDT0000.enable_dir_restripe)
20509         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20510         stack_trap "do_nodes $mdts $LCTL set_param \
20511                     mdt.*.enable_dir_restripe=$restripe_status"
20512
20513         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20514         createmany -m $DIR/$tdir/f 100 ||
20515                 error "create files under remote dir failed"
20516         createmany -d $DIR/$tdir/d 100 ||
20517                 error "create dirs under remote dir failed"
20518
20519         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20520                 local mdt_hash="crush"
20521
20522                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20523                 $LFS setdirstripe -c $c $DIR/$tdir ||
20524                         error "split -c $c $tdir failed"
20525                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20526                         mdt_hash="$mdt_hash,fixed"
20527                 elif [ $c -eq 1 ]; then
20528                         mdt_hash="none"
20529                 fi
20530                 wait_update $HOSTNAME \
20531                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20532                         error "dir merge not finished"
20533                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20534                         awk '/migrate/ {sum += $2} END { print sum }')
20535                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20536                 # delta is around total_files/stripe_count
20537                 (( delta < 200 / c + 4 )) ||
20538                         error "$delta files migrated >= $((200 / c + 4))"
20539         done
20540 }
20541 run_test 230p "dir merge"
20542
20543 test_230q() {
20544         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20545         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20546                 skip "Need MDS version at least 2.13.52"
20547
20548         local mdts=$(comma_list $(mdts_nodes))
20549         local saved_threshold=$(do_facet mds1 \
20550                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20551         local saved_delta=$(do_facet mds1 \
20552                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20553         local threshold=100
20554         local delta=2
20555         local total=0
20556         local stripe_count=0
20557         local stripe_index
20558         local nr_files
20559         local create
20560
20561         # test with fewer files on ZFS
20562         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20563
20564         stack_trap "do_nodes $mdts $LCTL set_param \
20565                     mdt.*.dir_split_count=$saved_threshold"
20566         stack_trap "do_nodes $mdts $LCTL set_param \
20567                     mdt.*.dir_split_delta=$saved_delta"
20568         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20569         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20570         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20571         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20572         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20573         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20574
20575         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20576         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20577
20578         create=$((threshold * 3 / 2))
20579         while [ $stripe_count -lt $MDSCOUNT ]; do
20580                 createmany -m $DIR/$tdir/f $total $create ||
20581                         error "create sub files failed"
20582                 stat $DIR/$tdir > /dev/null
20583                 total=$((total + create))
20584                 stripe_count=$((stripe_count + delta))
20585                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20586
20587                 wait_update $HOSTNAME \
20588                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20589                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20590
20591                 wait_update $HOSTNAME \
20592                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20593                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20594
20595                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20596                 echo "$nr_files/$total files on MDT$stripe_index after split"
20597                 # allow 10% margin of imbalance with crush hash
20598                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20599                         error "$nr_files files on MDT$stripe_index after split"
20600
20601                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20602                 [ $nr_files -eq $total ] ||
20603                         error "total sub files $nr_files != $total"
20604         done
20605
20606         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20607
20608         echo "fixed layout directory won't auto split"
20609         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20610         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20611                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20612         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20613                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20614 }
20615 run_test 230q "dir auto split"
20616
20617 test_230r() {
20618         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20619         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20620         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20621                 skip "Need MDS version at least 2.13.54"
20622
20623         # maximum amount of local locks:
20624         # parent striped dir - 2 locks
20625         # new stripe in parent to migrate to - 1 lock
20626         # source and target - 2 locks
20627         # Total 5 locks for regular file
20628         mkdir -p $DIR/$tdir
20629         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20630         touch $DIR/$tdir/dir1/eee
20631
20632         # create 4 hardlink for 4 more locks
20633         # Total: 9 locks > RS_MAX_LOCKS (8)
20634         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20635         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20636         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20637         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20638         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20639         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20640         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20641         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20642
20643         cancel_lru_locks mdc
20644
20645         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20646                 error "migrate dir fails"
20647
20648         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20649 }
20650 run_test 230r "migrate with too many local locks"
20651
20652 test_230s() {
20653         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20654                 skip "Need MDS version at least 2.14.52"
20655
20656         local mdts=$(comma_list $(mdts_nodes))
20657         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20658                                 mdt.*MDT0000.enable_dir_restripe)
20659
20660         stack_trap "do_nodes $mdts $LCTL set_param \
20661                     mdt.*.enable_dir_restripe=$restripe_status"
20662
20663         local st
20664         for st in 0 1; do
20665                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20666                 test_mkdir $DIR/$tdir
20667                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20668                         error "$LFS mkdir should return EEXIST if target exists"
20669                 rmdir $DIR/$tdir
20670         done
20671 }
20672 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20673
20674 test_230t()
20675 {
20676         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20677         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20678                 skip "Need MDS version at least 2.14.50"
20679
20680         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20681         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20682         $LFS project -p 1 -s $DIR/$tdir ||
20683                 error "set $tdir project id failed"
20684         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20685                 error "set subdir project id failed"
20686         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20687 }
20688 run_test 230t "migrate directory with project ID set"
20689
20690 test_230u()
20691 {
20692         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20693         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20694                 skip "Need MDS version at least 2.14.53"
20695
20696         local count
20697
20698         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20699         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20700         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20701         for i in $(seq 0 $((MDSCOUNT - 1))); do
20702                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20703                 echo "$count dirs migrated to MDT$i"
20704         done
20705         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20706         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20707 }
20708 run_test 230u "migrate directory by QOS"
20709
20710 test_230v()
20711 {
20712         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20713         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20714                 skip "Need MDS version at least 2.14.53"
20715
20716         local count
20717
20718         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20719         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20720         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20721         for i in $(seq 0 $((MDSCOUNT - 1))); do
20722                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20723                 echo "$count subdirs migrated to MDT$i"
20724                 (( i == 3 )) && (( count > 0 )) &&
20725                         error "subdir shouldn't be migrated to MDT3"
20726         done
20727         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20728         (( count == 3 )) || error "dirs migrated to $count MDTs"
20729 }
20730 run_test 230v "subdir migrated to the MDT where its parent is located"
20731
20732 test_230w() {
20733         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20734         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20735                 skip "Need MDS version at least 2.14.53"
20736
20737         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20738
20739         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20740                 error "migrate failed"
20741
20742         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20743                 error "$tdir stripe count mismatch"
20744
20745         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20746                 error "$tdir/sub is striped"
20747 }
20748 run_test 230w "non-recursive mode dir migration"
20749
20750 test_231a()
20751 {
20752         # For simplicity this test assumes that max_pages_per_rpc
20753         # is the same across all OSCs
20754         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20755         local bulk_size=$((max_pages * PAGE_SIZE))
20756         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20757                                        head -n 1)
20758
20759         mkdir -p $DIR/$tdir
20760         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20761                 error "failed to set stripe with -S ${brw_size}M option"
20762
20763         # clear the OSC stats
20764         $LCTL set_param osc.*.stats=0 &>/dev/null
20765         stop_writeback
20766
20767         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20768         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20769                 oflag=direct &>/dev/null || error "dd failed"
20770
20771         sync; sleep 1; sync # just to be safe
20772         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20773         if [ x$nrpcs != "x1" ]; then
20774                 $LCTL get_param osc.*.stats
20775                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20776         fi
20777
20778         start_writeback
20779         # Drop the OSC cache, otherwise we will read from it
20780         cancel_lru_locks osc
20781
20782         # clear the OSC stats
20783         $LCTL set_param osc.*.stats=0 &>/dev/null
20784
20785         # Client reads $bulk_size.
20786         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20787                 iflag=direct &>/dev/null || error "dd failed"
20788
20789         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20790         if [ x$nrpcs != "x1" ]; then
20791                 $LCTL get_param osc.*.stats
20792                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20793         fi
20794 }
20795 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20796
20797 test_231b() {
20798         mkdir -p $DIR/$tdir
20799         local i
20800         for i in {0..1023}; do
20801                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20802                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20803                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20804         done
20805         sync
20806 }
20807 run_test 231b "must not assert on fully utilized OST request buffer"
20808
20809 test_232a() {
20810         mkdir -p $DIR/$tdir
20811         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20812
20813         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20814         do_facet ost1 $LCTL set_param fail_loc=0x31c
20815
20816         # ignore dd failure
20817         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20818
20819         do_facet ost1 $LCTL set_param fail_loc=0
20820         umount_client $MOUNT || error "umount failed"
20821         mount_client $MOUNT || error "mount failed"
20822         stop ost1 || error "cannot stop ost1"
20823         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20824 }
20825 run_test 232a "failed lock should not block umount"
20826
20827 test_232b() {
20828         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20829                 skip "Need MDS version at least 2.10.58"
20830
20831         mkdir -p $DIR/$tdir
20832         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20833         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20834         sync
20835         cancel_lru_locks osc
20836
20837         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20838         do_facet ost1 $LCTL set_param fail_loc=0x31c
20839
20840         # ignore failure
20841         $LFS data_version $DIR/$tdir/$tfile || true
20842
20843         do_facet ost1 $LCTL set_param fail_loc=0
20844         umount_client $MOUNT || error "umount failed"
20845         mount_client $MOUNT || error "mount failed"
20846         stop ost1 || error "cannot stop ost1"
20847         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20848 }
20849 run_test 232b "failed data version lock should not block umount"
20850
20851 test_233a() {
20852         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20853                 skip "Need MDS version at least 2.3.64"
20854         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20855
20856         local fid=$($LFS path2fid $MOUNT)
20857
20858         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20859                 error "cannot access $MOUNT using its FID '$fid'"
20860 }
20861 run_test 233a "checking that OBF of the FS root succeeds"
20862
20863 test_233b() {
20864         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20865                 skip "Need MDS version at least 2.5.90"
20866         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20867
20868         local fid=$($LFS path2fid $MOUNT/.lustre)
20869
20870         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20871                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20872
20873         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20874         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20875                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20876 }
20877 run_test 233b "checking that OBF of the FS .lustre succeeds"
20878
20879 test_234() {
20880         local p="$TMP/sanityN-$TESTNAME.parameters"
20881         save_lustre_params client "llite.*.xattr_cache" > $p
20882         lctl set_param llite.*.xattr_cache 1 ||
20883                 skip_env "xattr cache is not supported"
20884
20885         mkdir -p $DIR/$tdir || error "mkdir failed"
20886         touch $DIR/$tdir/$tfile || error "touch failed"
20887         # OBD_FAIL_LLITE_XATTR_ENOMEM
20888         $LCTL set_param fail_loc=0x1405
20889         getfattr -n user.attr $DIR/$tdir/$tfile &&
20890                 error "getfattr should have failed with ENOMEM"
20891         $LCTL set_param fail_loc=0x0
20892         rm -rf $DIR/$tdir
20893
20894         restore_lustre_params < $p
20895         rm -f $p
20896 }
20897 run_test 234 "xattr cache should not crash on ENOMEM"
20898
20899 test_235() {
20900         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20901                 skip "Need MDS version at least 2.4.52"
20902
20903         flock_deadlock $DIR/$tfile
20904         local RC=$?
20905         case $RC in
20906                 0)
20907                 ;;
20908                 124) error "process hangs on a deadlock"
20909                 ;;
20910                 *) error "error executing flock_deadlock $DIR/$tfile"
20911                 ;;
20912         esac
20913 }
20914 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20915
20916 #LU-2935
20917 test_236() {
20918         check_swap_layouts_support
20919
20920         local ref1=/etc/passwd
20921         local ref2=/etc/group
20922         local file1=$DIR/$tdir/f1
20923         local file2=$DIR/$tdir/f2
20924
20925         test_mkdir -c1 $DIR/$tdir
20926         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20927         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20928         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20929         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20930         local fd=$(free_fd)
20931         local cmd="exec $fd<>$file2"
20932         eval $cmd
20933         rm $file2
20934         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20935                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20936         cmd="exec $fd>&-"
20937         eval $cmd
20938         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20939
20940         #cleanup
20941         rm -rf $DIR/$tdir
20942 }
20943 run_test 236 "Layout swap on open unlinked file"
20944
20945 # LU-4659 linkea consistency
20946 test_238() {
20947         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20948                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20949                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20950                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20951
20952         touch $DIR/$tfile
20953         ln $DIR/$tfile $DIR/$tfile.lnk
20954         touch $DIR/$tfile.new
20955         mv $DIR/$tfile.new $DIR/$tfile
20956         local fid1=$($LFS path2fid $DIR/$tfile)
20957         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20958         local path1=$($LFS fid2path $FSNAME "$fid1")
20959         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20960         local path2=$($LFS fid2path $FSNAME "$fid2")
20961         [ $tfile.lnk == $path2 ] ||
20962                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20963         rm -f $DIR/$tfile*
20964 }
20965 run_test 238 "Verify linkea consistency"
20966
20967 test_239A() { # was test_239
20968         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20969                 skip "Need MDS version at least 2.5.60"
20970
20971         local list=$(comma_list $(mdts_nodes))
20972
20973         mkdir -p $DIR/$tdir
20974         createmany -o $DIR/$tdir/f- 5000
20975         unlinkmany $DIR/$tdir/f- 5000
20976         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20977                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20978         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20979                         osp.*MDT*.sync_in_flight" | calc_sum)
20980         [ "$changes" -eq 0 ] || error "$changes not synced"
20981 }
20982 run_test 239A "osp_sync test"
20983
20984 test_239a() { #LU-5297
20985         remote_mds_nodsh && skip "remote MDS with nodsh"
20986
20987         touch $DIR/$tfile
20988         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20989         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20990         chgrp $RUNAS_GID $DIR/$tfile
20991         wait_delete_completed
20992 }
20993 run_test 239a "process invalid osp sync record correctly"
20994
20995 test_239b() { #LU-5297
20996         remote_mds_nodsh && skip "remote MDS with nodsh"
20997
20998         touch $DIR/$tfile1
20999         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21000         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21001         chgrp $RUNAS_GID $DIR/$tfile1
21002         wait_delete_completed
21003         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21004         touch $DIR/$tfile2
21005         chgrp $RUNAS_GID $DIR/$tfile2
21006         wait_delete_completed
21007 }
21008 run_test 239b "process osp sync record with ENOMEM error correctly"
21009
21010 test_240() {
21011         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21012         remote_mds_nodsh && skip "remote MDS with nodsh"
21013
21014         mkdir -p $DIR/$tdir
21015
21016         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21017                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21018         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21019                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21020
21021         umount_client $MOUNT || error "umount failed"
21022         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21023         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21024         mount_client $MOUNT || error "failed to mount client"
21025
21026         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21027         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21028 }
21029 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21030
21031 test_241_bio() {
21032         local count=$1
21033         local bsize=$2
21034
21035         for LOOP in $(seq $count); do
21036                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21037                 cancel_lru_locks $OSC || true
21038         done
21039 }
21040
21041 test_241_dio() {
21042         local count=$1
21043         local bsize=$2
21044
21045         for LOOP in $(seq $1); do
21046                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21047                         2>/dev/null
21048         done
21049 }
21050
21051 test_241a() { # was test_241
21052         local bsize=$PAGE_SIZE
21053
21054         (( bsize < 40960 )) && bsize=40960
21055         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21056         ls -la $DIR/$tfile
21057         cancel_lru_locks $OSC
21058         test_241_bio 1000 $bsize &
21059         PID=$!
21060         test_241_dio 1000 $bsize
21061         wait $PID
21062 }
21063 run_test 241a "bio vs dio"
21064
21065 test_241b() {
21066         local bsize=$PAGE_SIZE
21067
21068         (( bsize < 40960 )) && bsize=40960
21069         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21070         ls -la $DIR/$tfile
21071         test_241_dio 1000 $bsize &
21072         PID=$!
21073         test_241_dio 1000 $bsize
21074         wait $PID
21075 }
21076 run_test 241b "dio vs dio"
21077
21078 test_242() {
21079         remote_mds_nodsh && skip "remote MDS with nodsh"
21080
21081         mkdir_on_mdt0 $DIR/$tdir
21082         touch $DIR/$tdir/$tfile
21083
21084         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21085         do_facet mds1 lctl set_param fail_loc=0x105
21086         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21087
21088         do_facet mds1 lctl set_param fail_loc=0
21089         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21090 }
21091 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21092
21093 test_243()
21094 {
21095         test_mkdir $DIR/$tdir
21096         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21097 }
21098 run_test 243 "various group lock tests"
21099
21100 test_244a()
21101 {
21102         test_mkdir $DIR/$tdir
21103         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21104         sendfile_grouplock $DIR/$tdir/$tfile || \
21105                 error "sendfile+grouplock failed"
21106         rm -rf $DIR/$tdir
21107 }
21108 run_test 244a "sendfile with group lock tests"
21109
21110 test_244b()
21111 {
21112         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21113
21114         local threads=50
21115         local size=$((1024*1024))
21116
21117         test_mkdir $DIR/$tdir
21118         for i in $(seq 1 $threads); do
21119                 local file=$DIR/$tdir/file_$((i / 10))
21120                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21121                 local pids[$i]=$!
21122         done
21123         for i in $(seq 1 $threads); do
21124                 wait ${pids[$i]}
21125         done
21126 }
21127 run_test 244b "multi-threaded write with group lock"
21128
21129 test_245a() {
21130         local flagname="multi_mod_rpcs"
21131         local connect_data_name="max_mod_rpcs"
21132         local out
21133
21134         # check if multiple modify RPCs flag is set
21135         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21136                 grep "connect_flags:")
21137         echo "$out"
21138
21139         echo "$out" | grep -qw $flagname
21140         if [ $? -ne 0 ]; then
21141                 echo "connect flag $flagname is not set"
21142                 return
21143         fi
21144
21145         # check if multiple modify RPCs data is set
21146         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21147         echo "$out"
21148
21149         echo "$out" | grep -qw $connect_data_name ||
21150                 error "import should have connect data $connect_data_name"
21151 }
21152 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21153
21154 test_245b() {
21155         local flagname="multi_mod_rpcs"
21156         local connect_data_name="max_mod_rpcs"
21157         local out
21158
21159         remote_mds_nodsh && skip "remote MDS with nodsh"
21160         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21161
21162         # check if multiple modify RPCs flag is set
21163         out=$(do_facet mds1 \
21164               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21165               grep "connect_flags:")
21166         echo "$out"
21167
21168         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21169
21170         # check if multiple modify RPCs data is set
21171         out=$(do_facet mds1 \
21172               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21173
21174         [[ "$out" =~ $connect_data_name ]] ||
21175                 {
21176                         echo "$out"
21177                         error "missing connect data $connect_data_name"
21178                 }
21179 }
21180 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21181
21182 cleanup_247() {
21183         local submount=$1
21184
21185         trap 0
21186         umount_client $submount
21187         rmdir $submount
21188 }
21189
21190 test_247a() {
21191         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21192                 grep -q subtree ||
21193                 skip_env "Fileset feature is not supported"
21194
21195         local submount=${MOUNT}_$tdir
21196
21197         mkdir $MOUNT/$tdir
21198         mkdir -p $submount || error "mkdir $submount failed"
21199         FILESET="$FILESET/$tdir" mount_client $submount ||
21200                 error "mount $submount failed"
21201         trap "cleanup_247 $submount" EXIT
21202         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21203         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21204                 error "read $MOUNT/$tdir/$tfile failed"
21205         cleanup_247 $submount
21206 }
21207 run_test 247a "mount subdir as fileset"
21208
21209 test_247b() {
21210         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21211                 skip_env "Fileset feature is not supported"
21212
21213         local submount=${MOUNT}_$tdir
21214
21215         rm -rf $MOUNT/$tdir
21216         mkdir -p $submount || error "mkdir $submount failed"
21217         SKIP_FILESET=1
21218         FILESET="$FILESET/$tdir" mount_client $submount &&
21219                 error "mount $submount should fail"
21220         rmdir $submount
21221 }
21222 run_test 247b "mount subdir that dose not exist"
21223
21224 test_247c() {
21225         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21226                 skip_env "Fileset feature is not supported"
21227
21228         local submount=${MOUNT}_$tdir
21229
21230         mkdir -p $MOUNT/$tdir/dir1
21231         mkdir -p $submount || error "mkdir $submount failed"
21232         trap "cleanup_247 $submount" EXIT
21233         FILESET="$FILESET/$tdir" mount_client $submount ||
21234                 error "mount $submount failed"
21235         local fid=$($LFS path2fid $MOUNT/)
21236         $LFS fid2path $submount $fid && error "fid2path should fail"
21237         cleanup_247 $submount
21238 }
21239 run_test 247c "running fid2path outside subdirectory root"
21240
21241 test_247d() {
21242         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21243                 skip "Fileset feature is not supported"
21244
21245         local submount=${MOUNT}_$tdir
21246
21247         mkdir -p $MOUNT/$tdir/dir1
21248         mkdir -p $submount || error "mkdir $submount failed"
21249         FILESET="$FILESET/$tdir" mount_client $submount ||
21250                 error "mount $submount failed"
21251         trap "cleanup_247 $submount" EXIT
21252
21253         local td=$submount/dir1
21254         local fid=$($LFS path2fid $td)
21255         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21256
21257         # check that we get the same pathname back
21258         local rootpath
21259         local found
21260         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21261                 echo "$rootpath $fid"
21262                 found=$($LFS fid2path $rootpath "$fid")
21263                 [ -n "$found" ] || error "fid2path should succeed"
21264                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21265         done
21266         # check wrong root path format
21267         rootpath=$submount"_wrong"
21268         found=$($LFS fid2path $rootpath "$fid")
21269         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21270
21271         cleanup_247 $submount
21272 }
21273 run_test 247d "running fid2path inside subdirectory root"
21274
21275 # LU-8037
21276 test_247e() {
21277         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21278                 grep -q subtree ||
21279                 skip "Fileset feature is not supported"
21280
21281         local submount=${MOUNT}_$tdir
21282
21283         mkdir $MOUNT/$tdir
21284         mkdir -p $submount || error "mkdir $submount failed"
21285         FILESET="$FILESET/.." mount_client $submount &&
21286                 error "mount $submount should fail"
21287         rmdir $submount
21288 }
21289 run_test 247e "mount .. as fileset"
21290
21291 test_247f() {
21292         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21293         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21294                 skip "Need at least version 2.13.52"
21295         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21296                 skip "Need at least version 2.14.50"
21297         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21298                 grep -q subtree ||
21299                 skip "Fileset feature is not supported"
21300
21301         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21302         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21303                 error "mkdir remote failed"
21304         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21305                 error "mkdir remote/subdir failed"
21306         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21307                 error "mkdir striped failed"
21308         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21309
21310         local submount=${MOUNT}_$tdir
21311
21312         mkdir -p $submount || error "mkdir $submount failed"
21313         stack_trap "rmdir $submount"
21314
21315         local dir
21316         local stat
21317         local fileset=$FILESET
21318         local mdts=$(comma_list $(mdts_nodes))
21319
21320         stat=$(do_facet mds1 $LCTL get_param -n \
21321                 mdt.*MDT0000.enable_remote_subdir_mount)
21322         stack_trap "do_nodes $mdts $LCTL set_param \
21323                 mdt.*.enable_remote_subdir_mount=$stat"
21324
21325         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21326         stack_trap "umount_client $submount"
21327         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21328                 error "mount remote dir $dir should fail"
21329
21330         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21331                 $tdir/striped/. ; do
21332                 FILESET="$fileset/$dir" mount_client $submount ||
21333                         error "mount $dir failed"
21334                 umount_client $submount
21335         done
21336
21337         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21338         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21339                 error "mount $tdir/remote failed"
21340 }
21341 run_test 247f "mount striped or remote directory as fileset"
21342
21343 test_247g() {
21344         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21345         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21346                 skip "Need at least version 2.14.50"
21347
21348         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21349                 error "mkdir $tdir failed"
21350         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21351
21352         local submount=${MOUNT}_$tdir
21353
21354         mkdir -p $submount || error "mkdir $submount failed"
21355         stack_trap "rmdir $submount"
21356
21357         FILESET="$fileset/$tdir" mount_client $submount ||
21358                 error "mount $dir failed"
21359         stack_trap "umount $submount"
21360
21361         local mdts=$(comma_list $(mdts_nodes))
21362
21363         local nrpcs
21364
21365         stat $submount > /dev/null
21366         cancel_lru_locks $MDC
21367         stat $submount > /dev/null
21368         stat $submount/$tfile > /dev/null
21369         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21370         stat $submount/$tfile > /dev/null
21371         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21372                 awk '/getattr/ {sum += $2} END {print sum}')
21373
21374         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21375 }
21376 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21377
21378 test_248a() {
21379         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21380         [ -z "$fast_read_sav" ] && skip "no fast read support"
21381
21382         # create a large file for fast read verification
21383         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21384
21385         # make sure the file is created correctly
21386         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21387                 { rm -f $DIR/$tfile; skip "file creation error"; }
21388
21389         echo "Test 1: verify that fast read is 4 times faster on cache read"
21390
21391         # small read with fast read enabled
21392         $LCTL set_param -n llite.*.fast_read=1
21393         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21394                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21395                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21396         # small read with fast read disabled
21397         $LCTL set_param -n llite.*.fast_read=0
21398         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21399                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21400                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21401
21402         # verify that fast read is 4 times faster for cache read
21403         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21404                 error_not_in_vm "fast read was not 4 times faster: " \
21405                            "$t_fast vs $t_slow"
21406
21407         echo "Test 2: verify the performance between big and small read"
21408         $LCTL set_param -n llite.*.fast_read=1
21409
21410         # 1k non-cache read
21411         cancel_lru_locks osc
21412         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21413                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21414                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21415
21416         # 1M non-cache read
21417         cancel_lru_locks osc
21418         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21419                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21420                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21421
21422         # verify that big IO is not 4 times faster than small IO
21423         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21424                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21425
21426         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21427         rm -f $DIR/$tfile
21428 }
21429 run_test 248a "fast read verification"
21430
21431 test_248b() {
21432         # Default short_io_bytes=16384, try both smaller and larger sizes.
21433         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21434         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21435         echo "bs=53248 count=113 normal buffered write"
21436         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21437                 error "dd of initial data file failed"
21438         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21439
21440         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21441         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21442                 error "dd with sync normal writes failed"
21443         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21444
21445         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21446         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21447                 error "dd with sync small writes failed"
21448         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21449
21450         cancel_lru_locks osc
21451
21452         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21453         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21454         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21455         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21456                 iflag=direct || error "dd with O_DIRECT small read failed"
21457         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21458         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21459                 error "compare $TMP/$tfile.1 failed"
21460
21461         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21462         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21463
21464         # just to see what the maximum tunable value is, and test parsing
21465         echo "test invalid parameter 2MB"
21466         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21467                 error "too-large short_io_bytes allowed"
21468         echo "test maximum parameter 512KB"
21469         # if we can set a larger short_io_bytes, run test regardless of version
21470         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21471                 # older clients may not allow setting it this large, that's OK
21472                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21473                         skip "Need at least client version 2.13.50"
21474                 error "medium short_io_bytes failed"
21475         fi
21476         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21477         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21478
21479         echo "test large parameter 64KB"
21480         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21481         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21482
21483         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21484         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21485                 error "dd with sync large writes failed"
21486         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21487
21488         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21489         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21490         num=$((113 * 4096 / PAGE_SIZE))
21491         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21492         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21493                 error "dd with O_DIRECT large writes failed"
21494         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21495                 error "compare $DIR/$tfile.3 failed"
21496
21497         cancel_lru_locks osc
21498
21499         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21500         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21501                 error "dd with O_DIRECT large read failed"
21502         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21503                 error "compare $TMP/$tfile.2 failed"
21504
21505         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21506         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21507                 error "dd with O_DIRECT large read failed"
21508         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21509                 error "compare $TMP/$tfile.3 failed"
21510 }
21511 run_test 248b "test short_io read and write for both small and large sizes"
21512
21513 test_249() { # LU-7890
21514         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21515                 skip "Need at least version 2.8.54"
21516
21517         rm -f $DIR/$tfile
21518         $LFS setstripe -c 1 $DIR/$tfile
21519         # Offset 2T == 4k * 512M
21520         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21521                 error "dd to 2T offset failed"
21522 }
21523 run_test 249 "Write above 2T file size"
21524
21525 test_250() {
21526         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21527          && skip "no 16TB file size limit on ZFS"
21528
21529         $LFS setstripe -c 1 $DIR/$tfile
21530         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21531         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21532         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21533         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21534                 conv=notrunc,fsync && error "append succeeded"
21535         return 0
21536 }
21537 run_test 250 "Write above 16T limit"
21538
21539 test_251() {
21540         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21541
21542         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21543         #Skip once - writing the first stripe will succeed
21544         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21545         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21546                 error "short write happened"
21547
21548         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21549         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21550                 error "short read happened"
21551
21552         rm -f $DIR/$tfile
21553 }
21554 run_test 251 "Handling short read and write correctly"
21555
21556 test_252() {
21557         remote_mds_nodsh && skip "remote MDS with nodsh"
21558         remote_ost_nodsh && skip "remote OST with nodsh"
21559         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21560                 skip_env "ldiskfs only test"
21561         fi
21562
21563         local tgt
21564         local dev
21565         local out
21566         local uuid
21567         local num
21568         local gen
21569
21570         # check lr_reader on OST0000
21571         tgt=ost1
21572         dev=$(facet_device $tgt)
21573         out=$(do_facet $tgt $LR_READER $dev)
21574         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21575         echo "$out"
21576         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21577         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21578                 error "Invalid uuid returned by $LR_READER on target $tgt"
21579         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21580
21581         # check lr_reader -c on MDT0000
21582         tgt=mds1
21583         dev=$(facet_device $tgt)
21584         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21585                 skip "$LR_READER does not support additional options"
21586         fi
21587         out=$(do_facet $tgt $LR_READER -c $dev)
21588         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21589         echo "$out"
21590         num=$(echo "$out" | grep -c "mdtlov")
21591         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21592                 error "Invalid number of mdtlov clients returned by $LR_READER"
21593         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21594
21595         # check lr_reader -cr on MDT0000
21596         out=$(do_facet $tgt $LR_READER -cr $dev)
21597         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21598         echo "$out"
21599         echo "$out" | grep -q "^reply_data:$" ||
21600                 error "$LR_READER should have returned 'reply_data' section"
21601         num=$(echo "$out" | grep -c "client_generation")
21602         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21603 }
21604 run_test 252 "check lr_reader tool"
21605
21606 test_253() {
21607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21608         remote_mds_nodsh && skip "remote MDS with nodsh"
21609         remote_mgs_nodsh && skip "remote MGS with nodsh"
21610
21611         local ostidx=0
21612         local rc=0
21613         local ost_name=$(ostname_from_index $ostidx)
21614
21615         # on the mdt's osc
21616         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21617         do_facet $SINGLEMDS $LCTL get_param -n \
21618                 osp.$mdtosc_proc1.reserved_mb_high ||
21619                 skip  "remote MDS does not support reserved_mb_high"
21620
21621         rm -rf $DIR/$tdir
21622         wait_mds_ost_sync
21623         wait_delete_completed
21624         mkdir $DIR/$tdir
21625
21626         pool_add $TESTNAME || error "Pool creation failed"
21627         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21628
21629         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21630                 error "Setstripe failed"
21631
21632         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21633
21634         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21635                     grep "watermarks")
21636         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21637
21638         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21639                         osp.$mdtosc_proc1.prealloc_status)
21640         echo "prealloc_status $oa_status"
21641
21642         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21643                 error "File creation should fail"
21644
21645         #object allocation was stopped, but we still able to append files
21646         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21647                 oflag=append || error "Append failed"
21648
21649         rm -f $DIR/$tdir/$tfile.0
21650
21651         # For this test, we want to delete the files we created to go out of
21652         # space but leave the watermark, so we remain nearly out of space
21653         ost_watermarks_enospc_delete_files $tfile $ostidx
21654
21655         wait_delete_completed
21656
21657         sleep_maxage
21658
21659         for i in $(seq 10 12); do
21660                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21661                         2>/dev/null || error "File creation failed after rm"
21662         done
21663
21664         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21665                         osp.$mdtosc_proc1.prealloc_status)
21666         echo "prealloc_status $oa_status"
21667
21668         if (( oa_status != 0 )); then
21669                 error "Object allocation still disable after rm"
21670         fi
21671 }
21672 run_test 253 "Check object allocation limit"
21673
21674 test_254() {
21675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21676         remote_mds_nodsh && skip "remote MDS with nodsh"
21677
21678         local mdt=$(facet_svc $SINGLEMDS)
21679
21680         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21681                 skip "MDS does not support changelog_size"
21682
21683         local cl_user
21684
21685         changelog_register || error "changelog_register failed"
21686
21687         changelog_clear 0 || error "changelog_clear failed"
21688
21689         local size1=$(do_facet $SINGLEMDS \
21690                       $LCTL get_param -n mdd.$mdt.changelog_size)
21691         echo "Changelog size $size1"
21692
21693         rm -rf $DIR/$tdir
21694         $LFS mkdir -i 0 $DIR/$tdir
21695         # change something
21696         mkdir -p $DIR/$tdir/pics/2008/zachy
21697         touch $DIR/$tdir/pics/2008/zachy/timestamp
21698         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21699         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21700         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21701         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21702         rm $DIR/$tdir/pics/desktop.jpg
21703
21704         local size2=$(do_facet $SINGLEMDS \
21705                       $LCTL get_param -n mdd.$mdt.changelog_size)
21706         echo "Changelog size after work $size2"
21707
21708         (( $size2 > $size1 )) ||
21709                 error "new Changelog size=$size2 less than old size=$size1"
21710 }
21711 run_test 254 "Check changelog size"
21712
21713 ladvise_no_type()
21714 {
21715         local type=$1
21716         local file=$2
21717
21718         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21719                 awk -F: '{print $2}' | grep $type > /dev/null
21720         if [ $? -ne 0 ]; then
21721                 return 0
21722         fi
21723         return 1
21724 }
21725
21726 ladvise_no_ioctl()
21727 {
21728         local file=$1
21729
21730         lfs ladvise -a willread $file > /dev/null 2>&1
21731         if [ $? -eq 0 ]; then
21732                 return 1
21733         fi
21734
21735         lfs ladvise -a willread $file 2>&1 |
21736                 grep "Inappropriate ioctl for device" > /dev/null
21737         if [ $? -eq 0 ]; then
21738                 return 0
21739         fi
21740         return 1
21741 }
21742
21743 percent() {
21744         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21745 }
21746
21747 # run a random read IO workload
21748 # usage: random_read_iops <filename> <filesize> <iosize>
21749 random_read_iops() {
21750         local file=$1
21751         local fsize=$2
21752         local iosize=${3:-4096}
21753
21754         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21755                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21756 }
21757
21758 drop_file_oss_cache() {
21759         local file="$1"
21760         local nodes="$2"
21761
21762         $LFS ladvise -a dontneed $file 2>/dev/null ||
21763                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21764 }
21765
21766 ladvise_willread_performance()
21767 {
21768         local repeat=10
21769         local average_origin=0
21770         local average_cache=0
21771         local average_ladvise=0
21772
21773         for ((i = 1; i <= $repeat; i++)); do
21774                 echo "Iter $i/$repeat: reading without willread hint"
21775                 cancel_lru_locks osc
21776                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21777                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21778                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21779                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21780
21781                 cancel_lru_locks osc
21782                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21783                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21784                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21785
21786                 cancel_lru_locks osc
21787                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21788                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21789                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21790                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21791                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21792         done
21793         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21794         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21795         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21796
21797         speedup_cache=$(percent $average_cache $average_origin)
21798         speedup_ladvise=$(percent $average_ladvise $average_origin)
21799
21800         echo "Average uncached read: $average_origin"
21801         echo "Average speedup with OSS cached read: " \
21802                 "$average_cache = +$speedup_cache%"
21803         echo "Average speedup with ladvise willread: " \
21804                 "$average_ladvise = +$speedup_ladvise%"
21805
21806         local lowest_speedup=20
21807         if (( ${average_cache%.*} < $lowest_speedup )); then
21808                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21809                      " got $average_cache%. Skipping ladvise willread check."
21810                 return 0
21811         fi
21812
21813         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21814         # it is still good to run until then to exercise 'ladvise willread'
21815         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21816                 [ "$ost1_FSTYPE" = "zfs" ] &&
21817                 echo "osd-zfs does not support dontneed or drop_caches" &&
21818                 return 0
21819
21820         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21821         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21822                 error_not_in_vm "Speedup with willread is less than " \
21823                         "$lowest_speedup%, got $average_ladvise%"
21824 }
21825
21826 test_255a() {
21827         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21828                 skip "lustre < 2.8.54 does not support ladvise "
21829         remote_ost_nodsh && skip "remote OST with nodsh"
21830
21831         stack_trap "rm -f $DIR/$tfile"
21832         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21833
21834         ladvise_no_type willread $DIR/$tfile &&
21835                 skip "willread ladvise is not supported"
21836
21837         ladvise_no_ioctl $DIR/$tfile &&
21838                 skip "ladvise ioctl is not supported"
21839
21840         local size_mb=100
21841         local size=$((size_mb * 1048576))
21842         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21843                 error "dd to $DIR/$tfile failed"
21844
21845         lfs ladvise -a willread $DIR/$tfile ||
21846                 error "Ladvise failed with no range argument"
21847
21848         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21849                 error "Ladvise failed with no -l or -e argument"
21850
21851         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21852                 error "Ladvise failed with only -e argument"
21853
21854         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21855                 error "Ladvise failed with only -l argument"
21856
21857         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21858                 error "End offset should not be smaller than start offset"
21859
21860         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21861                 error "End offset should not be equal to start offset"
21862
21863         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21864                 error "Ladvise failed with overflowing -s argument"
21865
21866         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21867                 error "Ladvise failed with overflowing -e argument"
21868
21869         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21870                 error "Ladvise failed with overflowing -l argument"
21871
21872         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21873                 error "Ladvise succeeded with conflicting -l and -e arguments"
21874
21875         echo "Synchronous ladvise should wait"
21876         local delay=4
21877 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21878         do_nodes $(comma_list $(osts_nodes)) \
21879                 $LCTL set_param fail_val=$delay fail_loc=0x237
21880
21881         local start_ts=$SECONDS
21882         lfs ladvise -a willread $DIR/$tfile ||
21883                 error "Ladvise failed with no range argument"
21884         local end_ts=$SECONDS
21885         local inteval_ts=$((end_ts - start_ts))
21886
21887         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21888                 error "Synchronous advice didn't wait reply"
21889         fi
21890
21891         echo "Asynchronous ladvise shouldn't wait"
21892         local start_ts=$SECONDS
21893         lfs ladvise -a willread -b $DIR/$tfile ||
21894                 error "Ladvise failed with no range argument"
21895         local end_ts=$SECONDS
21896         local inteval_ts=$((end_ts - start_ts))
21897
21898         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21899                 error "Asynchronous advice blocked"
21900         fi
21901
21902         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21903         ladvise_willread_performance
21904 }
21905 run_test 255a "check 'lfs ladvise -a willread'"
21906
21907 facet_meminfo() {
21908         local facet=$1
21909         local info=$2
21910
21911         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21912 }
21913
21914 test_255b() {
21915         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21916                 skip "lustre < 2.8.54 does not support ladvise "
21917         remote_ost_nodsh && skip "remote OST with nodsh"
21918
21919         stack_trap "rm -f $DIR/$tfile"
21920         lfs setstripe -c 1 -i 0 $DIR/$tfile
21921
21922         ladvise_no_type dontneed $DIR/$tfile &&
21923                 skip "dontneed ladvise is not supported"
21924
21925         ladvise_no_ioctl $DIR/$tfile &&
21926                 skip "ladvise ioctl is not supported"
21927
21928         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21929                 [ "$ost1_FSTYPE" = "zfs" ] &&
21930                 skip "zfs-osd does not support 'ladvise dontneed'"
21931
21932         local size_mb=100
21933         local size=$((size_mb * 1048576))
21934         # In order to prevent disturbance of other processes, only check 3/4
21935         # of the memory usage
21936         local kibibytes=$((size_mb * 1024 * 3 / 4))
21937
21938         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21939                 error "dd to $DIR/$tfile failed"
21940
21941         #force write to complete before dropping OST cache & checking memory
21942         sync
21943
21944         local total=$(facet_meminfo ost1 MemTotal)
21945         echo "Total memory: $total KiB"
21946
21947         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21948         local before_read=$(facet_meminfo ost1 Cached)
21949         echo "Cache used before read: $before_read KiB"
21950
21951         lfs ladvise -a willread $DIR/$tfile ||
21952                 error "Ladvise willread failed"
21953         local after_read=$(facet_meminfo ost1 Cached)
21954         echo "Cache used after read: $after_read KiB"
21955
21956         lfs ladvise -a dontneed $DIR/$tfile ||
21957                 error "Ladvise dontneed again failed"
21958         local no_read=$(facet_meminfo ost1 Cached)
21959         echo "Cache used after dontneed ladvise: $no_read KiB"
21960
21961         if [ $total -lt $((before_read + kibibytes)) ]; then
21962                 echo "Memory is too small, abort checking"
21963                 return 0
21964         fi
21965
21966         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21967                 error "Ladvise willread should use more memory" \
21968                         "than $kibibytes KiB"
21969         fi
21970
21971         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21972                 error "Ladvise dontneed should release more memory" \
21973                         "than $kibibytes KiB"
21974         fi
21975 }
21976 run_test 255b "check 'lfs ladvise -a dontneed'"
21977
21978 test_255c() {
21979         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21980                 skip "lustre < 2.10.50 does not support lockahead"
21981
21982         local ost1_imp=$(get_osc_import_name client ost1)
21983         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21984                          cut -d'.' -f2)
21985         local count
21986         local new_count
21987         local difference
21988         local i
21989         local rc
21990
21991         test_mkdir -p $DIR/$tdir
21992         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21993
21994         #test 10 returns only success/failure
21995         i=10
21996         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21997         rc=$?
21998         if [ $rc -eq 255 ]; then
21999                 error "Ladvise test${i} failed, ${rc}"
22000         fi
22001
22002         #test 11 counts lock enqueue requests, all others count new locks
22003         i=11
22004         count=$(do_facet ost1 \
22005                 $LCTL get_param -n ost.OSS.ost.stats)
22006         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22007
22008         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22009         rc=$?
22010         if [ $rc -eq 255 ]; then
22011                 error "Ladvise test${i} failed, ${rc}"
22012         fi
22013
22014         new_count=$(do_facet ost1 \
22015                 $LCTL get_param -n ost.OSS.ost.stats)
22016         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22017                    awk '{ print $2 }')
22018
22019         difference="$((new_count - count))"
22020         if [ $difference -ne $rc ]; then
22021                 error "Ladvise test${i}, bad enqueue count, returned " \
22022                       "${rc}, actual ${difference}"
22023         fi
22024
22025         for i in $(seq 12 21); do
22026                 # If we do not do this, we run the risk of having too many
22027                 # locks and starting lock cancellation while we are checking
22028                 # lock counts.
22029                 cancel_lru_locks osc
22030
22031                 count=$($LCTL get_param -n \
22032                        ldlm.namespaces.$imp_name.lock_unused_count)
22033
22034                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22035                 rc=$?
22036                 if [ $rc -eq 255 ]; then
22037                         error "Ladvise test ${i} failed, ${rc}"
22038                 fi
22039
22040                 new_count=$($LCTL get_param -n \
22041                        ldlm.namespaces.$imp_name.lock_unused_count)
22042                 difference="$((new_count - count))"
22043
22044                 # Test 15 output is divided by 100 to map down to valid return
22045                 if [ $i -eq 15 ]; then
22046                         rc="$((rc * 100))"
22047                 fi
22048
22049                 if [ $difference -ne $rc ]; then
22050                         error "Ladvise test ${i}, bad lock count, returned " \
22051                               "${rc}, actual ${difference}"
22052                 fi
22053         done
22054
22055         #test 22 returns only success/failure
22056         i=22
22057         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22058         rc=$?
22059         if [ $rc -eq 255 ]; then
22060                 error "Ladvise test${i} failed, ${rc}"
22061         fi
22062 }
22063 run_test 255c "suite of ladvise lockahead tests"
22064
22065 test_256() {
22066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22067         remote_mds_nodsh && skip "remote MDS with nodsh"
22068         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22069         changelog_users $SINGLEMDS | grep "^cl" &&
22070                 skip "active changelog user"
22071
22072         local cl_user
22073         local cat_sl
22074         local mdt_dev
22075
22076         mdt_dev=$(facet_device $SINGLEMDS)
22077         echo $mdt_dev
22078
22079         changelog_register || error "changelog_register failed"
22080
22081         rm -rf $DIR/$tdir
22082         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22083
22084         changelog_clear 0 || error "changelog_clear failed"
22085
22086         # change something
22087         touch $DIR/$tdir/{1..10}
22088
22089         # stop the MDT
22090         stop $SINGLEMDS || error "Fail to stop MDT"
22091
22092         # remount the MDT
22093         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22094                 error "Fail to start MDT"
22095
22096         #after mount new plainllog is used
22097         touch $DIR/$tdir/{11..19}
22098         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22099         stack_trap "rm -f $tmpfile"
22100         cat_sl=$(do_facet $SINGLEMDS "sync; \
22101                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22102                  llog_reader $tmpfile | grep -c type=1064553b")
22103         do_facet $SINGLEMDS llog_reader $tmpfile
22104
22105         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22106
22107         changelog_clear 0 || error "changelog_clear failed"
22108
22109         cat_sl=$(do_facet $SINGLEMDS "sync; \
22110                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22111                  llog_reader $tmpfile | grep -c type=1064553b")
22112
22113         if (( cat_sl == 2 )); then
22114                 error "Empty plain llog was not deleted from changelog catalog"
22115         elif (( cat_sl != 1 )); then
22116                 error "Active plain llog shouldn't be deleted from catalog"
22117         fi
22118 }
22119 run_test 256 "Check llog delete for empty and not full state"
22120
22121 test_257() {
22122         remote_mds_nodsh && skip "remote MDS with nodsh"
22123         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22124                 skip "Need MDS version at least 2.8.55"
22125
22126         test_mkdir $DIR/$tdir
22127
22128         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22129                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22130         stat $DIR/$tdir
22131
22132 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22133         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22134         local facet=mds$((mdtidx + 1))
22135         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22136         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22137
22138         stop $facet || error "stop MDS failed"
22139         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22140                 error "start MDS fail"
22141         wait_recovery_complete $facet
22142 }
22143 run_test 257 "xattr locks are not lost"
22144
22145 # Verify we take the i_mutex when security requires it
22146 test_258a() {
22147 #define OBD_FAIL_IMUTEX_SEC 0x141c
22148         $LCTL set_param fail_loc=0x141c
22149         touch $DIR/$tfile
22150         chmod u+s $DIR/$tfile
22151         chmod a+rwx $DIR/$tfile
22152         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22153         RC=$?
22154         if [ $RC -ne 0 ]; then
22155                 error "error, failed to take i_mutex, rc=$?"
22156         fi
22157         rm -f $DIR/$tfile
22158 }
22159 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22160
22161 # Verify we do NOT take the i_mutex in the normal case
22162 test_258b() {
22163 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22164         $LCTL set_param fail_loc=0x141d
22165         touch $DIR/$tfile
22166         chmod a+rwx $DIR
22167         chmod a+rw $DIR/$tfile
22168         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22169         RC=$?
22170         if [ $RC -ne 0 ]; then
22171                 error "error, took i_mutex unnecessarily, rc=$?"
22172         fi
22173         rm -f $DIR/$tfile
22174
22175 }
22176 run_test 258b "verify i_mutex security behavior"
22177
22178 test_259() {
22179         local file=$DIR/$tfile
22180         local before
22181         local after
22182
22183         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22184
22185         stack_trap "rm -f $file" EXIT
22186
22187         wait_delete_completed
22188         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22189         echo "before: $before"
22190
22191         $LFS setstripe -i 0 -c 1 $file
22192         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22193         sync_all_data
22194         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22195         echo "after write: $after"
22196
22197 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22198         do_facet ost1 $LCTL set_param fail_loc=0x2301
22199         $TRUNCATE $file 0
22200         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22201         echo "after truncate: $after"
22202
22203         stop ost1
22204         do_facet ost1 $LCTL set_param fail_loc=0
22205         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22206         sleep 2
22207         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22208         echo "after restart: $after"
22209         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22210                 error "missing truncate?"
22211
22212         return 0
22213 }
22214 run_test 259 "crash at delayed truncate"
22215
22216 test_260() {
22217 #define OBD_FAIL_MDC_CLOSE               0x806
22218         $LCTL set_param fail_loc=0x80000806
22219         touch $DIR/$tfile
22220
22221 }
22222 run_test 260 "Check mdc_close fail"
22223
22224 ### Data-on-MDT sanity tests ###
22225 test_270a() {
22226         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22227                 skip "Need MDS version at least 2.10.55 for DoM"
22228
22229         # create DoM file
22230         local dom=$DIR/$tdir/dom_file
22231         local tmp=$DIR/$tdir/tmp_file
22232
22233         mkdir_on_mdt0 $DIR/$tdir
22234
22235         # basic checks for DoM component creation
22236         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22237                 error "Can set MDT layout to non-first entry"
22238
22239         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22240                 error "Can define multiple entries as MDT layout"
22241
22242         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22243
22244         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22245         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22246         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22247
22248         local mdtidx=$($LFS getstripe -m $dom)
22249         local mdtname=MDT$(printf %04x $mdtidx)
22250         local facet=mds$((mdtidx + 1))
22251         local space_check=1
22252
22253         # Skip free space checks with ZFS
22254         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22255
22256         # write
22257         sync
22258         local size_tmp=$((65536 * 3))
22259         local mdtfree1=$(do_facet $facet \
22260                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22261
22262         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22263         # check also direct IO along write
22264         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22265         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22266         sync
22267         cmp $tmp $dom || error "file data is different"
22268         [ $(stat -c%s $dom) == $size_tmp ] ||
22269                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22270         if [ $space_check == 1 ]; then
22271                 local mdtfree2=$(do_facet $facet \
22272                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22273
22274                 # increase in usage from by $size_tmp
22275                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22276                         error "MDT free space wrong after write: " \
22277                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22278         fi
22279
22280         # truncate
22281         local size_dom=10000
22282
22283         $TRUNCATE $dom $size_dom
22284         [ $(stat -c%s $dom) == $size_dom ] ||
22285                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22286         if [ $space_check == 1 ]; then
22287                 mdtfree1=$(do_facet $facet \
22288                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22289                 # decrease in usage from $size_tmp to new $size_dom
22290                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22291                   $(((size_tmp - size_dom) / 1024)) ] ||
22292                         error "MDT free space is wrong after truncate: " \
22293                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22294         fi
22295
22296         # append
22297         cat $tmp >> $dom
22298         sync
22299         size_dom=$((size_dom + size_tmp))
22300         [ $(stat -c%s $dom) == $size_dom ] ||
22301                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22302         if [ $space_check == 1 ]; then
22303                 mdtfree2=$(do_facet $facet \
22304                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22305                 # increase in usage by $size_tmp from previous
22306                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22307                         error "MDT free space is wrong after append: " \
22308                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22309         fi
22310
22311         # delete
22312         rm $dom
22313         if [ $space_check == 1 ]; then
22314                 mdtfree1=$(do_facet $facet \
22315                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22316                 # decrease in usage by $size_dom from previous
22317                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22318                         error "MDT free space is wrong after removal: " \
22319                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22320         fi
22321
22322         # combined striping
22323         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22324                 error "Can't create DoM + OST striping"
22325
22326         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22327         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22328         # check also direct IO along write
22329         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22330         sync
22331         cmp $tmp $dom || error "file data is different"
22332         [ $(stat -c%s $dom) == $size_tmp ] ||
22333                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22334         rm $dom $tmp
22335
22336         return 0
22337 }
22338 run_test 270a "DoM: basic functionality tests"
22339
22340 test_270b() {
22341         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22342                 skip "Need MDS version at least 2.10.55"
22343
22344         local dom=$DIR/$tdir/dom_file
22345         local max_size=1048576
22346
22347         mkdir -p $DIR/$tdir
22348         $LFS setstripe -E $max_size -L mdt $dom
22349
22350         # truncate over the limit
22351         $TRUNCATE $dom $(($max_size + 1)) &&
22352                 error "successful truncate over the maximum size"
22353         # write over the limit
22354         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22355                 error "successful write over the maximum size"
22356         # append over the limit
22357         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22358         echo "12345" >> $dom && error "successful append over the maximum size"
22359         rm $dom
22360
22361         return 0
22362 }
22363 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22364
22365 test_270c() {
22366         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22367                 skip "Need MDS version at least 2.10.55"
22368
22369         mkdir -p $DIR/$tdir
22370         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22371
22372         # check files inherit DoM EA
22373         touch $DIR/$tdir/first
22374         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22375                 error "bad pattern"
22376         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22377                 error "bad stripe count"
22378         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22379                 error "bad stripe size"
22380
22381         # check directory inherits DoM EA and uses it as default
22382         mkdir $DIR/$tdir/subdir
22383         touch $DIR/$tdir/subdir/second
22384         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22385                 error "bad pattern in sub-directory"
22386         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22387                 error "bad stripe count in sub-directory"
22388         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22389                 error "bad stripe size in sub-directory"
22390         return 0
22391 }
22392 run_test 270c "DoM: DoM EA inheritance tests"
22393
22394 test_270d() {
22395         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22396                 skip "Need MDS version at least 2.10.55"
22397
22398         mkdir -p $DIR/$tdir
22399         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22400
22401         # inherit default DoM striping
22402         mkdir $DIR/$tdir/subdir
22403         touch $DIR/$tdir/subdir/f1
22404
22405         # change default directory striping
22406         $LFS setstripe -c 1 $DIR/$tdir/subdir
22407         touch $DIR/$tdir/subdir/f2
22408         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22409                 error "wrong default striping in file 2"
22410         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22411                 error "bad pattern in file 2"
22412         return 0
22413 }
22414 run_test 270d "DoM: change striping from DoM to RAID0"
22415
22416 test_270e() {
22417         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22418                 skip "Need MDS version at least 2.10.55"
22419
22420         mkdir -p $DIR/$tdir/dom
22421         mkdir -p $DIR/$tdir/norm
22422         DOMFILES=20
22423         NORMFILES=10
22424         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22425         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22426
22427         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22428         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22429
22430         # find DoM files by layout
22431         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22432         [ $NUM -eq  $DOMFILES ] ||
22433                 error "lfs find -L: found $NUM, expected $DOMFILES"
22434         echo "Test 1: lfs find 20 DOM files by layout: OK"
22435
22436         # there should be 1 dir with default DOM striping
22437         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22438         [ $NUM -eq  1 ] ||
22439                 error "lfs find -L: found $NUM, expected 1 dir"
22440         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22441
22442         # find DoM files by stripe size
22443         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22444         [ $NUM -eq  $DOMFILES ] ||
22445                 error "lfs find -S: found $NUM, expected $DOMFILES"
22446         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22447
22448         # find files by stripe offset except DoM files
22449         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22450         [ $NUM -eq  $NORMFILES ] ||
22451                 error "lfs find -i: found $NUM, expected $NORMFILES"
22452         echo "Test 5: lfs find no DOM files by stripe index: OK"
22453         return 0
22454 }
22455 run_test 270e "DoM: lfs find with DoM files test"
22456
22457 test_270f() {
22458         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22459                 skip "Need MDS version at least 2.10.55"
22460
22461         local mdtname=${FSNAME}-MDT0000-mdtlov
22462         local dom=$DIR/$tdir/dom_file
22463         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22464                                                 lod.$mdtname.dom_stripesize)
22465         local dom_limit=131072
22466
22467         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22468         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22469                                                 lod.$mdtname.dom_stripesize)
22470         [ ${dom_limit} -eq ${dom_current} ] ||
22471                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22472
22473         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22474         $LFS setstripe -d $DIR/$tdir
22475         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22476                 error "Can't set directory default striping"
22477
22478         # exceed maximum stripe size
22479         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22480                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22481         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22482                 error "Able to create DoM component size more than LOD limit"
22483
22484         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22485         dom_current=$(do_facet mds1 $LCTL get_param -n \
22486                                                 lod.$mdtname.dom_stripesize)
22487         [ 0 -eq ${dom_current} ] ||
22488                 error "Can't set zero DoM stripe limit"
22489         rm $dom
22490
22491         # attempt to create DoM file on server with disabled DoM should
22492         # remove DoM entry from layout and be succeed
22493         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22494                 error "Can't create DoM file (DoM is disabled)"
22495         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22496                 error "File has DoM component while DoM is disabled"
22497         rm $dom
22498
22499         # attempt to create DoM file with only DoM stripe should return error
22500         $LFS setstripe -E $dom_limit -L mdt $dom &&
22501                 error "Able to create DoM-only file while DoM is disabled"
22502
22503         # too low values to be aligned with smallest stripe size 64K
22504         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22505         dom_current=$(do_facet mds1 $LCTL get_param -n \
22506                                                 lod.$mdtname.dom_stripesize)
22507         [ 30000 -eq ${dom_current} ] &&
22508                 error "Can set too small DoM stripe limit"
22509
22510         # 64K is a minimal stripe size in Lustre, expect limit of that size
22511         [ 65536 -eq ${dom_current} ] ||
22512                 error "Limit is not set to 64K but ${dom_current}"
22513
22514         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22515         dom_current=$(do_facet mds1 $LCTL get_param -n \
22516                                                 lod.$mdtname.dom_stripesize)
22517         echo $dom_current
22518         [ 2147483648 -eq ${dom_current} ] &&
22519                 error "Can set too large DoM stripe limit"
22520
22521         do_facet mds1 $LCTL set_param -n \
22522                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22523         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22524                 error "Can't create DoM component size after limit change"
22525         do_facet mds1 $LCTL set_param -n \
22526                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22527         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22528                 error "Can't create DoM file after limit decrease"
22529         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22530                 error "Can create big DoM component after limit decrease"
22531         touch ${dom}_def ||
22532                 error "Can't create file with old default layout"
22533
22534         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22535         return 0
22536 }
22537 run_test 270f "DoM: maximum DoM stripe size checks"
22538
22539 test_270g() {
22540         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22541                 skip "Need MDS version at least 2.13.52"
22542         local dom=$DIR/$tdir/$tfile
22543
22544         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22545         local lodname=${FSNAME}-MDT0000-mdtlov
22546
22547         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22548         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22549         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22550         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22551
22552         local dom_limit=1024
22553         local dom_threshold="50%"
22554
22555         $LFS setstripe -d $DIR/$tdir
22556         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22557                 error "Can't set directory default striping"
22558
22559         do_facet mds1 $LCTL set_param -n \
22560                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22561         # set 0 threshold and create DOM file to change tunable stripesize
22562         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22563         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22564                 error "Failed to create $dom file"
22565         # now tunable dom_cur_stripesize should reach maximum
22566         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22567                                         lod.${lodname}.dom_stripesize_cur_kb)
22568         [[ $dom_current == $dom_limit ]] ||
22569                 error "Current DOM stripesize is not maximum"
22570         rm $dom
22571
22572         # set threshold for further tests
22573         do_facet mds1 $LCTL set_param -n \
22574                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22575         echo "DOM threshold is $dom_threshold free space"
22576         local dom_def
22577         local dom_set
22578         # Spoof bfree to exceed threshold
22579         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22580         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22581         for spfree in 40 20 0 15 30 55; do
22582                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22583                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22584                         error "Failed to create $dom file"
22585                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22586                                         lod.${lodname}.dom_stripesize_cur_kb)
22587                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22588                 [[ $dom_def != $dom_current ]] ||
22589                         error "Default stripe size was not changed"
22590                 if (( spfree > 0 )) ; then
22591                         dom_set=$($LFS getstripe -S $dom)
22592                         (( dom_set == dom_def * 1024 )) ||
22593                                 error "DOM component size is still old"
22594                 else
22595                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22596                                 error "DoM component is set with no free space"
22597                 fi
22598                 rm $dom
22599                 dom_current=$dom_def
22600         done
22601 }
22602 run_test 270g "DoM: default DoM stripe size depends on free space"
22603
22604 test_270h() {
22605         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22606                 skip "Need MDS version at least 2.13.53"
22607
22608         local mdtname=${FSNAME}-MDT0000-mdtlov
22609         local dom=$DIR/$tdir/$tfile
22610         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22611
22612         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22613         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22614
22615         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22616         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22617                 error "can't create OST file"
22618         # mirrored file with DOM entry in the second mirror
22619         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22620                 error "can't create mirror with DoM component"
22621
22622         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22623
22624         # DOM component in the middle and has other enries in the same mirror,
22625         # should succeed but lost DoM component
22626         $LFS setstripe --copy=${dom}_1 $dom ||
22627                 error "Can't create file from OST|DOM mirror layout"
22628         # check new file has no DoM layout after all
22629         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22630                 error "File has DoM component while DoM is disabled"
22631 }
22632 run_test 270h "DoM: DoM stripe removal when disabled on server"
22633
22634 test_270i() {
22635         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22636                 skip "Need MDS version at least 2.14.54"
22637
22638         mkdir $DIR/$tdir
22639         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22640                 error "setstripe should fail" || true
22641 }
22642 run_test 270i "DoM: setting invalid DoM striping should fail"
22643
22644 test_271a() {
22645         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22646                 skip "Need MDS version at least 2.10.55"
22647
22648         local dom=$DIR/$tdir/dom
22649
22650         mkdir -p $DIR/$tdir
22651
22652         $LFS setstripe -E 1024K -L mdt $dom
22653
22654         lctl set_param -n mdc.*.stats=clear
22655         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22656         cat $dom > /dev/null
22657         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22658         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22659         ls $dom
22660         rm -f $dom
22661 }
22662 run_test 271a "DoM: data is cached for read after write"
22663
22664 test_271b() {
22665         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22666                 skip "Need MDS version at least 2.10.55"
22667
22668         local dom=$DIR/$tdir/dom
22669
22670         mkdir -p $DIR/$tdir
22671
22672         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22673
22674         lctl set_param -n mdc.*.stats=clear
22675         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22676         cancel_lru_locks mdc
22677         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22678         # second stat to check size is cached on client
22679         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22680         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22681         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22682         rm -f $dom
22683 }
22684 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22685
22686 test_271ba() {
22687         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22688                 skip "Need MDS version at least 2.10.55"
22689
22690         local dom=$DIR/$tdir/dom
22691
22692         mkdir -p $DIR/$tdir
22693
22694         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22695
22696         lctl set_param -n mdc.*.stats=clear
22697         lctl set_param -n osc.*.stats=clear
22698         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22699         cancel_lru_locks mdc
22700         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22701         # second stat to check size is cached on client
22702         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22703         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22704         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22705         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22706         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22707         rm -f $dom
22708 }
22709 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22710
22711
22712 get_mdc_stats() {
22713         local mdtidx=$1
22714         local param=$2
22715         local mdt=MDT$(printf %04x $mdtidx)
22716
22717         if [ -z $param ]; then
22718                 lctl get_param -n mdc.*$mdt*.stats
22719         else
22720                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22721         fi
22722 }
22723
22724 test_271c() {
22725         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22726                 skip "Need MDS version at least 2.10.55"
22727
22728         local dom=$DIR/$tdir/dom
22729
22730         mkdir -p $DIR/$tdir
22731
22732         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22733
22734         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22735         local facet=mds$((mdtidx + 1))
22736
22737         cancel_lru_locks mdc
22738         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22739         createmany -o $dom 1000
22740         lctl set_param -n mdc.*.stats=clear
22741         smalliomany -w $dom 1000 200
22742         get_mdc_stats $mdtidx
22743         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22744         # Each file has 1 open, 1 IO enqueues, total 2000
22745         # but now we have also +1 getxattr for security.capability, total 3000
22746         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22747         unlinkmany $dom 1000
22748
22749         cancel_lru_locks mdc
22750         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22751         createmany -o $dom 1000
22752         lctl set_param -n mdc.*.stats=clear
22753         smalliomany -w $dom 1000 200
22754         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22755         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22756         # for OPEN and IO lock.
22757         [ $((enq - enq_2)) -ge 1000 ] ||
22758                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22759         unlinkmany $dom 1000
22760         return 0
22761 }
22762 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22763
22764 cleanup_271def_tests() {
22765         trap 0
22766         rm -f $1
22767 }
22768
22769 test_271d() {
22770         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22771                 skip "Need MDS version at least 2.10.57"
22772
22773         local dom=$DIR/$tdir/dom
22774         local tmp=$TMP/$tfile
22775         trap "cleanup_271def_tests $tmp" EXIT
22776
22777         mkdir -p $DIR/$tdir
22778
22779         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22780
22781         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22782
22783         cancel_lru_locks mdc
22784         dd if=/dev/urandom of=$tmp bs=1000 count=1
22785         dd if=$tmp of=$dom bs=1000 count=1
22786         cancel_lru_locks mdc
22787
22788         cat /etc/hosts >> $tmp
22789         lctl set_param -n mdc.*.stats=clear
22790
22791         # append data to the same file it should update local page
22792         echo "Append to the same page"
22793         cat /etc/hosts >> $dom
22794         local num=$(get_mdc_stats $mdtidx ost_read)
22795         local ra=$(get_mdc_stats $mdtidx req_active)
22796         local rw=$(get_mdc_stats $mdtidx req_waittime)
22797
22798         [ -z $num ] || error "$num READ RPC occured"
22799         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22800         echo "... DONE"
22801
22802         # compare content
22803         cmp $tmp $dom || error "file miscompare"
22804
22805         cancel_lru_locks mdc
22806         lctl set_param -n mdc.*.stats=clear
22807
22808         echo "Open and read file"
22809         cat $dom > /dev/null
22810         local num=$(get_mdc_stats $mdtidx ost_read)
22811         local ra=$(get_mdc_stats $mdtidx req_active)
22812         local rw=$(get_mdc_stats $mdtidx req_waittime)
22813
22814         [ -z $num ] || error "$num READ RPC occured"
22815         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22816         echo "... DONE"
22817
22818         # compare content
22819         cmp $tmp $dom || error "file miscompare"
22820
22821         return 0
22822 }
22823 run_test 271d "DoM: read on open (1K file in reply buffer)"
22824
22825 test_271f() {
22826         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22827                 skip "Need MDS version at least 2.10.57"
22828
22829         local dom=$DIR/$tdir/dom
22830         local tmp=$TMP/$tfile
22831         trap "cleanup_271def_tests $tmp" EXIT
22832
22833         mkdir -p $DIR/$tdir
22834
22835         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22836
22837         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22838
22839         cancel_lru_locks mdc
22840         dd if=/dev/urandom of=$tmp bs=265000 count=1
22841         dd if=$tmp of=$dom bs=265000 count=1
22842         cancel_lru_locks mdc
22843         cat /etc/hosts >> $tmp
22844         lctl set_param -n mdc.*.stats=clear
22845
22846         echo "Append to the same page"
22847         cat /etc/hosts >> $dom
22848         local num=$(get_mdc_stats $mdtidx ost_read)
22849         local ra=$(get_mdc_stats $mdtidx req_active)
22850         local rw=$(get_mdc_stats $mdtidx req_waittime)
22851
22852         [ -z $num ] || error "$num READ RPC occured"
22853         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22854         echo "... DONE"
22855
22856         # compare content
22857         cmp $tmp $dom || error "file miscompare"
22858
22859         cancel_lru_locks mdc
22860         lctl set_param -n mdc.*.stats=clear
22861
22862         echo "Open and read file"
22863         cat $dom > /dev/null
22864         local num=$(get_mdc_stats $mdtidx ost_read)
22865         local ra=$(get_mdc_stats $mdtidx req_active)
22866         local rw=$(get_mdc_stats $mdtidx req_waittime)
22867
22868         [ -z $num ] && num=0
22869         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22870         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22871         echo "... DONE"
22872
22873         # compare content
22874         cmp $tmp $dom || error "file miscompare"
22875
22876         return 0
22877 }
22878 run_test 271f "DoM: read on open (200K file and read tail)"
22879
22880 test_271g() {
22881         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22882                 skip "Skipping due to old client or server version"
22883
22884         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22885         # to get layout
22886         $CHECKSTAT -t file $DIR1/$tfile
22887
22888         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22889         MULTIOP_PID=$!
22890         sleep 1
22891         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22892         $LCTL set_param fail_loc=0x80000314
22893         rm $DIR1/$tfile || error "Unlink fails"
22894         RC=$?
22895         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22896         [ $RC -eq 0 ] || error "Failed write to stale object"
22897 }
22898 run_test 271g "Discard DoM data vs client flush race"
22899
22900 test_272a() {
22901         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22902                 skip "Need MDS version at least 2.11.50"
22903
22904         local dom=$DIR/$tdir/dom
22905         mkdir -p $DIR/$tdir
22906
22907         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22908         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22909                 error "failed to write data into $dom"
22910         local old_md5=$(md5sum $dom)
22911
22912         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22913                 error "failed to migrate to the same DoM component"
22914
22915         local new_md5=$(md5sum $dom)
22916
22917         [ "$old_md5" == "$new_md5" ] ||
22918                 error "md5sum differ: $old_md5, $new_md5"
22919
22920         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22921                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22922 }
22923 run_test 272a "DoM migration: new layout with the same DOM component"
22924
22925 test_272b() {
22926         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22927                 skip "Need MDS version at least 2.11.50"
22928
22929         local dom=$DIR/$tdir/dom
22930         mkdir -p $DIR/$tdir
22931         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22932
22933         local mdtidx=$($LFS getstripe -m $dom)
22934         local mdtname=MDT$(printf %04x $mdtidx)
22935         local facet=mds$((mdtidx + 1))
22936
22937         local mdtfree1=$(do_facet $facet \
22938                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22939         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22940                 error "failed to write data into $dom"
22941         local old_md5=$(md5sum $dom)
22942         cancel_lru_locks mdc
22943         local mdtfree1=$(do_facet $facet \
22944                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22945
22946         $LFS migrate -c2 $dom ||
22947                 error "failed to migrate to the new composite layout"
22948         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22949                 error "MDT stripe was not removed"
22950
22951         cancel_lru_locks mdc
22952         local new_md5=$(md5sum $dom)
22953         [ "$old_md5" == "$new_md5" ] ||
22954                 error "$old_md5 != $new_md5"
22955
22956         # Skip free space checks with ZFS
22957         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22958                 local mdtfree2=$(do_facet $facet \
22959                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22960                 [ $mdtfree2 -gt $mdtfree1 ] ||
22961                         error "MDT space is not freed after migration"
22962         fi
22963         return 0
22964 }
22965 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22966
22967 test_272c() {
22968         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22969                 skip "Need MDS version at least 2.11.50"
22970
22971         local dom=$DIR/$tdir/$tfile
22972         mkdir -p $DIR/$tdir
22973         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22974
22975         local mdtidx=$($LFS getstripe -m $dom)
22976         local mdtname=MDT$(printf %04x $mdtidx)
22977         local facet=mds$((mdtidx + 1))
22978
22979         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22980                 error "failed to write data into $dom"
22981         local old_md5=$(md5sum $dom)
22982         cancel_lru_locks mdc
22983         local mdtfree1=$(do_facet $facet \
22984                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22985
22986         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22987                 error "failed to migrate to the new composite layout"
22988         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22989                 error "MDT stripe was not removed"
22990
22991         cancel_lru_locks mdc
22992         local new_md5=$(md5sum $dom)
22993         [ "$old_md5" == "$new_md5" ] ||
22994                 error "$old_md5 != $new_md5"
22995
22996         # Skip free space checks with ZFS
22997         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22998                 local mdtfree2=$(do_facet $facet \
22999                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23000                 [ $mdtfree2 -gt $mdtfree1 ] ||
23001                         error "MDS space is not freed after migration"
23002         fi
23003         return 0
23004 }
23005 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23006
23007 test_272d() {
23008         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23009                 skip "Need MDS version at least 2.12.55"
23010
23011         local dom=$DIR/$tdir/$tfile
23012         mkdir -p $DIR/$tdir
23013         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23014
23015         local mdtidx=$($LFS getstripe -m $dom)
23016         local mdtname=MDT$(printf %04x $mdtidx)
23017         local facet=mds$((mdtidx + 1))
23018
23019         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23020                 error "failed to write data into $dom"
23021         local old_md5=$(md5sum $dom)
23022         cancel_lru_locks mdc
23023         local mdtfree1=$(do_facet $facet \
23024                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23025
23026         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23027                 error "failed mirroring to the new composite layout"
23028         $LFS mirror resync $dom ||
23029                 error "failed mirror resync"
23030         $LFS mirror split --mirror-id 1 -d $dom ||
23031                 error "failed mirror split"
23032
23033         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23034                 error "MDT stripe was not removed"
23035
23036         cancel_lru_locks mdc
23037         local new_md5=$(md5sum $dom)
23038         [ "$old_md5" == "$new_md5" ] ||
23039                 error "$old_md5 != $new_md5"
23040
23041         # Skip free space checks with ZFS
23042         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23043                 local mdtfree2=$(do_facet $facet \
23044                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23045                 [ $mdtfree2 -gt $mdtfree1 ] ||
23046                         error "MDS space is not freed after DOM mirror deletion"
23047         fi
23048         return 0
23049 }
23050 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23051
23052 test_272e() {
23053         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23054                 skip "Need MDS version at least 2.12.55"
23055
23056         local dom=$DIR/$tdir/$tfile
23057         mkdir -p $DIR/$tdir
23058         $LFS setstripe -c 2 $dom
23059
23060         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23061                 error "failed to write data into $dom"
23062         local old_md5=$(md5sum $dom)
23063         cancel_lru_locks
23064
23065         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23066                 error "failed mirroring to the DOM layout"
23067         $LFS mirror resync $dom ||
23068                 error "failed mirror resync"
23069         $LFS mirror split --mirror-id 1 -d $dom ||
23070                 error "failed mirror split"
23071
23072         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23073                 error "MDT stripe wasn't set"
23074
23075         cancel_lru_locks
23076         local new_md5=$(md5sum $dom)
23077         [ "$old_md5" == "$new_md5" ] ||
23078                 error "$old_md5 != $new_md5"
23079
23080         return 0
23081 }
23082 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23083
23084 test_272f() {
23085         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23086                 skip "Need MDS version at least 2.12.55"
23087
23088         local dom=$DIR/$tdir/$tfile
23089         mkdir -p $DIR/$tdir
23090         $LFS setstripe -c 2 $dom
23091
23092         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23093                 error "failed to write data into $dom"
23094         local old_md5=$(md5sum $dom)
23095         cancel_lru_locks
23096
23097         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23098                 error "failed migrating to the DOM file"
23099
23100         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23101                 error "MDT stripe wasn't set"
23102
23103         cancel_lru_locks
23104         local new_md5=$(md5sum $dom)
23105         [ "$old_md5" != "$new_md5" ] &&
23106                 error "$old_md5 != $new_md5"
23107
23108         return 0
23109 }
23110 run_test 272f "DoM migration: OST-striped file to DOM file"
23111
23112 test_273a() {
23113         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23114                 skip "Need MDS version at least 2.11.50"
23115
23116         # Layout swap cannot be done if either file has DOM component,
23117         # this will never be supported, migration should be used instead
23118
23119         local dom=$DIR/$tdir/$tfile
23120         mkdir -p $DIR/$tdir
23121
23122         $LFS setstripe -c2 ${dom}_plain
23123         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23124         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23125                 error "can swap layout with DoM component"
23126         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23127                 error "can swap layout with DoM component"
23128
23129         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23130         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23131                 error "can swap layout with DoM component"
23132         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23133                 error "can swap layout with DoM component"
23134         return 0
23135 }
23136 run_test 273a "DoM: layout swapping should fail with DOM"
23137
23138 test_273b() {
23139         mkdir -p $DIR/$tdir
23140         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23141
23142 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23143         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23144
23145         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23146 }
23147 run_test 273b "DoM: race writeback and object destroy"
23148
23149 test_275() {
23150         remote_ost_nodsh && skip "remote OST with nodsh"
23151         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23152                 skip "Need OST version >= 2.10.57"
23153
23154         local file=$DIR/$tfile
23155         local oss
23156
23157         oss=$(comma_list $(osts_nodes))
23158
23159         dd if=/dev/urandom of=$file bs=1M count=2 ||
23160                 error "failed to create a file"
23161         cancel_lru_locks osc
23162
23163         #lock 1
23164         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23165                 error "failed to read a file"
23166
23167 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23168         $LCTL set_param fail_loc=0x8000031f
23169
23170         cancel_lru_locks osc &
23171         sleep 1
23172
23173 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23174         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23175         #IO takes another lock, but matches the PENDING one
23176         #and places it to the IO RPC
23177         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23178                 error "failed to read a file with PENDING lock"
23179 }
23180 run_test 275 "Read on a canceled duplicate lock"
23181
23182 test_276() {
23183         remote_ost_nodsh && skip "remote OST with nodsh"
23184         local pid
23185
23186         do_facet ost1 "(while true; do \
23187                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23188                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23189         pid=$!
23190
23191         for LOOP in $(seq 20); do
23192                 stop ost1
23193                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23194         done
23195         kill -9 $pid
23196         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23197                 rm $TMP/sanity_276_pid"
23198 }
23199 run_test 276 "Race between mount and obd_statfs"
23200
23201 test_277() {
23202         $LCTL set_param ldlm.namespaces.*.lru_size=0
23203         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23204         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23205                         grep ^used_mb | awk '{print $2}')
23206         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23207         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23208                 oflag=direct conv=notrunc
23209         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23210                         grep ^used_mb | awk '{print $2}')
23211         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23212 }
23213 run_test 277 "Direct IO shall drop page cache"
23214
23215 test_278() {
23216         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23217         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23218         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23219                 skip "needs the same host for mdt1 mdt2" && return
23220
23221         local pid1
23222         local pid2
23223
23224 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23225         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23226         stop mds2 &
23227         pid2=$!
23228
23229         stop mds1
23230
23231         echo "Starting MDTs"
23232         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23233         wait $pid2
23234 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23235 #will return NULL
23236         do_facet mds2 $LCTL set_param fail_loc=0
23237
23238         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23239         wait_recovery_complete mds2
23240 }
23241 run_test 278 "Race starting MDS between MDTs stop/start"
23242
23243 test_280() {
23244         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23245                 skip "Need MGS version at least 2.13.52"
23246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23247         combined_mgs_mds || skip "needs combined MGS/MDT"
23248
23249         umount_client $MOUNT
23250 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23251         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23252
23253         mount_client $MOUNT &
23254         sleep 1
23255         stop mgs || error "stop mgs failed"
23256         #for a race mgs would crash
23257         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23258         # make sure we unmount client before remounting
23259         wait
23260         umount_client $MOUNT
23261         mount_client $MOUNT || error "mount client failed"
23262 }
23263 run_test 280 "Race between MGS umount and client llog processing"
23264
23265 cleanup_test_300() {
23266         trap 0
23267         umask $SAVE_UMASK
23268 }
23269 test_striped_dir() {
23270         local mdt_index=$1
23271         local stripe_count
23272         local stripe_index
23273
23274         mkdir -p $DIR/$tdir
23275
23276         SAVE_UMASK=$(umask)
23277         trap cleanup_test_300 RETURN EXIT
23278
23279         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23280                                                 $DIR/$tdir/striped_dir ||
23281                 error "set striped dir error"
23282
23283         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23284         [ "$mode" = "755" ] || error "expect 755 got $mode"
23285
23286         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23287                 error "getdirstripe failed"
23288         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23289         if [ "$stripe_count" != "2" ]; then
23290                 error "1:stripe_count is $stripe_count, expect 2"
23291         fi
23292         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23293         if [ "$stripe_count" != "2" ]; then
23294                 error "2:stripe_count is $stripe_count, expect 2"
23295         fi
23296
23297         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23298         if [ "$stripe_index" != "$mdt_index" ]; then
23299                 error "stripe_index is $stripe_index, expect $mdt_index"
23300         fi
23301
23302         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23303                 error "nlink error after create striped dir"
23304
23305         mkdir $DIR/$tdir/striped_dir/a
23306         mkdir $DIR/$tdir/striped_dir/b
23307
23308         stat $DIR/$tdir/striped_dir/a ||
23309                 error "create dir under striped dir failed"
23310         stat $DIR/$tdir/striped_dir/b ||
23311                 error "create dir under striped dir failed"
23312
23313         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23314                 error "nlink error after mkdir"
23315
23316         rmdir $DIR/$tdir/striped_dir/a
23317         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23318                 error "nlink error after rmdir"
23319
23320         rmdir $DIR/$tdir/striped_dir/b
23321         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23322                 error "nlink error after rmdir"
23323
23324         chattr +i $DIR/$tdir/striped_dir
23325         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23326                 error "immutable flags not working under striped dir!"
23327         chattr -i $DIR/$tdir/striped_dir
23328
23329         rmdir $DIR/$tdir/striped_dir ||
23330                 error "rmdir striped dir error"
23331
23332         cleanup_test_300
23333
23334         true
23335 }
23336
23337 test_300a() {
23338         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23339                 skip "skipped for lustre < 2.7.0"
23340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23341         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23342
23343         test_striped_dir 0 || error "failed on striped dir on MDT0"
23344         test_striped_dir 1 || error "failed on striped dir on MDT0"
23345 }
23346 run_test 300a "basic striped dir sanity test"
23347
23348 test_300b() {
23349         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23350                 skip "skipped for lustre < 2.7.0"
23351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23352         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23353
23354         local i
23355         local mtime1
23356         local mtime2
23357         local mtime3
23358
23359         test_mkdir $DIR/$tdir || error "mkdir fail"
23360         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23361                 error "set striped dir error"
23362         for i in {0..9}; do
23363                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23364                 sleep 1
23365                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23366                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23367                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23368                 sleep 1
23369                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23370                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23371                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23372         done
23373         true
23374 }
23375 run_test 300b "check ctime/mtime for striped dir"
23376
23377 test_300c() {
23378         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23379                 skip "skipped for lustre < 2.7.0"
23380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23382
23383         local file_count
23384
23385         mkdir_on_mdt0 $DIR/$tdir
23386         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23387                 error "set striped dir error"
23388
23389         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23390                 error "chown striped dir failed"
23391
23392         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23393                 error "create 5k files failed"
23394
23395         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23396
23397         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23398
23399         rm -rf $DIR/$tdir
23400 }
23401 run_test 300c "chown && check ls under striped directory"
23402
23403 test_300d() {
23404         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23405                 skip "skipped for lustre < 2.7.0"
23406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23408
23409         local stripe_count
23410         local file
23411
23412         mkdir -p $DIR/$tdir
23413         $LFS setstripe -c 2 $DIR/$tdir
23414
23415         #local striped directory
23416         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23417                 error "set striped dir error"
23418         #look at the directories for debug purposes
23419         ls -l $DIR/$tdir
23420         $LFS getdirstripe $DIR/$tdir
23421         ls -l $DIR/$tdir/striped_dir
23422         $LFS getdirstripe $DIR/$tdir/striped_dir
23423         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23424                 error "create 10 files failed"
23425
23426         #remote striped directory
23427         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23428                 error "set striped dir error"
23429         #look at the directories for debug purposes
23430         ls -l $DIR/$tdir
23431         $LFS getdirstripe $DIR/$tdir
23432         ls -l $DIR/$tdir/remote_striped_dir
23433         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23434         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23435                 error "create 10 files failed"
23436
23437         for file in $(find $DIR/$tdir); do
23438                 stripe_count=$($LFS getstripe -c $file)
23439                 [ $stripe_count -eq 2 ] ||
23440                         error "wrong stripe $stripe_count for $file"
23441         done
23442
23443         rm -rf $DIR/$tdir
23444 }
23445 run_test 300d "check default stripe under striped directory"
23446
23447 test_300e() {
23448         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23449                 skip "Need MDS version at least 2.7.55"
23450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23451         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23452
23453         local stripe_count
23454         local file
23455
23456         mkdir -p $DIR/$tdir
23457
23458         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23459                 error "set striped dir error"
23460
23461         touch $DIR/$tdir/striped_dir/a
23462         touch $DIR/$tdir/striped_dir/b
23463         touch $DIR/$tdir/striped_dir/c
23464
23465         mkdir $DIR/$tdir/striped_dir/dir_a
23466         mkdir $DIR/$tdir/striped_dir/dir_b
23467         mkdir $DIR/$tdir/striped_dir/dir_c
23468
23469         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23470                 error "set striped adir under striped dir error"
23471
23472         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23473                 error "set striped bdir under striped dir error"
23474
23475         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23476                 error "set striped cdir under striped dir error"
23477
23478         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23479                 error "rename dir under striped dir fails"
23480
23481         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23482                 error "rename dir under different stripes fails"
23483
23484         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23485                 error "rename file under striped dir should succeed"
23486
23487         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23488                 error "rename dir under striped dir should succeed"
23489
23490         rm -rf $DIR/$tdir
23491 }
23492 run_test 300e "check rename under striped directory"
23493
23494 test_300f() {
23495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23497         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23498                 skip "Need MDS version at least 2.7.55"
23499
23500         local stripe_count
23501         local file
23502
23503         rm -rf $DIR/$tdir
23504         mkdir -p $DIR/$tdir
23505
23506         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23507                 error "set striped dir error"
23508
23509         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23510                 error "set striped dir error"
23511
23512         touch $DIR/$tdir/striped_dir/a
23513         mkdir $DIR/$tdir/striped_dir/dir_a
23514         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23515                 error "create striped dir under striped dir fails"
23516
23517         touch $DIR/$tdir/striped_dir1/b
23518         mkdir $DIR/$tdir/striped_dir1/dir_b
23519         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23520                 error "create striped dir under striped dir fails"
23521
23522         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23523                 error "rename dir under different striped dir should fail"
23524
23525         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23526                 error "rename striped dir under diff striped dir should fail"
23527
23528         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23529                 error "rename file under diff striped dirs fails"
23530
23531         rm -rf $DIR/$tdir
23532 }
23533 run_test 300f "check rename cross striped directory"
23534
23535 test_300_check_default_striped_dir()
23536 {
23537         local dirname=$1
23538         local default_count=$2
23539         local default_index=$3
23540         local stripe_count
23541         local stripe_index
23542         local dir_stripe_index
23543         local dir
23544
23545         echo "checking $dirname $default_count $default_index"
23546         $LFS setdirstripe -D -c $default_count -i $default_index \
23547                                 -H all_char $DIR/$tdir/$dirname ||
23548                 error "set default stripe on striped dir error"
23549         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23550         [ $stripe_count -eq $default_count ] ||
23551                 error "expect $default_count get $stripe_count for $dirname"
23552
23553         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23554         [ $stripe_index -eq $default_index ] ||
23555                 error "expect $default_index get $stripe_index for $dirname"
23556
23557         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23558                                                 error "create dirs failed"
23559
23560         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23561         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23562         for dir in $(find $DIR/$tdir/$dirname/*); do
23563                 stripe_count=$($LFS getdirstripe -c $dir)
23564                 (( $stripe_count == $default_count )) ||
23565                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23566                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23567                 error "stripe count $default_count != $stripe_count for $dir"
23568
23569                 stripe_index=$($LFS getdirstripe -i $dir)
23570                 [ $default_index -eq -1 ] ||
23571                         [ $stripe_index -eq $default_index ] ||
23572                         error "$stripe_index != $default_index for $dir"
23573
23574                 #check default stripe
23575                 stripe_count=$($LFS getdirstripe -D -c $dir)
23576                 [ $stripe_count -eq $default_count ] ||
23577                 error "default count $default_count != $stripe_count for $dir"
23578
23579                 stripe_index=$($LFS getdirstripe -D -i $dir)
23580                 [ $stripe_index -eq $default_index ] ||
23581                 error "default index $default_index != $stripe_index for $dir"
23582         done
23583         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23584 }
23585
23586 test_300g() {
23587         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23588         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23589                 skip "Need MDS version at least 2.7.55"
23590
23591         local dir
23592         local stripe_count
23593         local stripe_index
23594
23595         mkdir_on_mdt0 $DIR/$tdir
23596         mkdir $DIR/$tdir/normal_dir
23597
23598         #Checking when client cache stripe index
23599         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23600         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23601                 error "create striped_dir failed"
23602
23603         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23604                 error "create dir0 fails"
23605         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23606         [ $stripe_index -eq 0 ] ||
23607                 error "dir0 expect index 0 got $stripe_index"
23608
23609         mkdir $DIR/$tdir/striped_dir/dir1 ||
23610                 error "create dir1 fails"
23611         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23612         [ $stripe_index -eq 1 ] ||
23613                 error "dir1 expect index 1 got $stripe_index"
23614
23615         #check default stripe count/stripe index
23616         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23617         test_300_check_default_striped_dir normal_dir 1 0
23618         test_300_check_default_striped_dir normal_dir -1 1
23619         test_300_check_default_striped_dir normal_dir 2 -1
23620
23621         #delete default stripe information
23622         echo "delete default stripeEA"
23623         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23624                 error "set default stripe on striped dir error"
23625
23626         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23627         for dir in $(find $DIR/$tdir/normal_dir/*); do
23628                 stripe_count=$($LFS getdirstripe -c $dir)
23629                 [ $stripe_count -eq 0 ] ||
23630                         error "expect 1 get $stripe_count for $dir"
23631         done
23632 }
23633 run_test 300g "check default striped directory for normal directory"
23634
23635 test_300h() {
23636         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23637         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23638                 skip "Need MDS version at least 2.7.55"
23639
23640         local dir
23641         local stripe_count
23642
23643         mkdir $DIR/$tdir
23644         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23645                 error "set striped dir error"
23646
23647         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23648         test_300_check_default_striped_dir striped_dir 1 0
23649         test_300_check_default_striped_dir striped_dir -1 1
23650         test_300_check_default_striped_dir striped_dir 2 -1
23651
23652         #delete default stripe information
23653         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23654                 error "set default stripe on striped dir error"
23655
23656         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23657         for dir in $(find $DIR/$tdir/striped_dir/*); do
23658                 stripe_count=$($LFS getdirstripe -c $dir)
23659                 [ $stripe_count -eq 0 ] ||
23660                         error "expect 1 get $stripe_count for $dir"
23661         done
23662 }
23663 run_test 300h "check default striped directory for striped directory"
23664
23665 test_300i() {
23666         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23667         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23668         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23669                 skip "Need MDS version at least 2.7.55"
23670
23671         local stripe_count
23672         local file
23673
23674         mkdir $DIR/$tdir
23675
23676         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23677                 error "set striped dir error"
23678
23679         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23680                 error "create files under striped dir failed"
23681
23682         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23683                 error "set striped hashdir error"
23684
23685         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23686                 error "create dir0 under hash dir failed"
23687         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23688                 error "create dir1 under hash dir failed"
23689         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23690                 error "create dir2 under hash dir failed"
23691
23692         # unfortunately, we need to umount to clear dir layout cache for now
23693         # once we fully implement dir layout, we can drop this
23694         umount_client $MOUNT || error "umount failed"
23695         mount_client $MOUNT || error "mount failed"
23696
23697         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23698         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23699         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23700
23701         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23702                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23703                         error "create crush2 dir $tdir/hashdir/d3 failed"
23704                 $LFS find -H crush2 $DIR/$tdir/hashdir
23705                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23706                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23707
23708                 # mkdir with an invalid hash type (hash=fail_val) from client
23709                 # should be replaced on MDS with a valid (default) hash type
23710                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23711                 $LCTL set_param fail_loc=0x1901 fail_val=99
23712                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23713
23714                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23715                 local expect=$(do_facet mds1 \
23716                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23717                 [[ $hash == $expect ]] ||
23718                         error "d99 hash '$hash' != expected hash '$expect'"
23719         fi
23720
23721         #set the stripe to be unknown hash type on read
23722         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23723         $LCTL set_param fail_loc=0x1901 fail_val=99
23724         for ((i = 0; i < 10; i++)); do
23725                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23726                         error "stat f-$i failed"
23727                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23728         done
23729
23730         touch $DIR/$tdir/striped_dir/f0 &&
23731                 error "create under striped dir with unknown hash should fail"
23732
23733         $LCTL set_param fail_loc=0
23734
23735         umount_client $MOUNT || error "umount failed"
23736         mount_client $MOUNT || error "mount failed"
23737
23738         return 0
23739 }
23740 run_test 300i "client handle unknown hash type striped directory"
23741
23742 test_300j() {
23743         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23745         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23746                 skip "Need MDS version at least 2.7.55"
23747
23748         local stripe_count
23749         local file
23750
23751         mkdir $DIR/$tdir
23752
23753         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23754         $LCTL set_param fail_loc=0x1702
23755         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23756                 error "set striped dir error"
23757
23758         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23759                 error "create files under striped dir failed"
23760
23761         $LCTL set_param fail_loc=0
23762
23763         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23764
23765         return 0
23766 }
23767 run_test 300j "test large update record"
23768
23769 test_300k() {
23770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23771         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23772         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23773                 skip "Need MDS version at least 2.7.55"
23774
23775         # this test needs a huge transaction
23776         local kb
23777         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23778              osd*.$FSNAME-MDT0000.kbytestotal")
23779         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23780
23781         local stripe_count
23782         local file
23783
23784         mkdir $DIR/$tdir
23785
23786         #define OBD_FAIL_LARGE_STRIPE   0x1703
23787         $LCTL set_param fail_loc=0x1703
23788         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23789                 error "set striped dir error"
23790         $LCTL set_param fail_loc=0
23791
23792         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23793                 error "getstripeddir fails"
23794         rm -rf $DIR/$tdir/striped_dir ||
23795                 error "unlink striped dir fails"
23796
23797         return 0
23798 }
23799 run_test 300k "test large striped directory"
23800
23801 test_300l() {
23802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23803         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23804         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23805                 skip "Need MDS version at least 2.7.55"
23806
23807         local stripe_index
23808
23809         test_mkdir -p $DIR/$tdir/striped_dir
23810         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23811                         error "chown $RUNAS_ID failed"
23812         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23813                 error "set default striped dir failed"
23814
23815         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23816         $LCTL set_param fail_loc=0x80000158
23817         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23818
23819         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23820         [ $stripe_index -eq 1 ] ||
23821                 error "expect 1 get $stripe_index for $dir"
23822 }
23823 run_test 300l "non-root user to create dir under striped dir with stale layout"
23824
23825 test_300m() {
23826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23827         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23828         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23829                 skip "Need MDS version at least 2.7.55"
23830
23831         mkdir -p $DIR/$tdir/striped_dir
23832         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23833                 error "set default stripes dir error"
23834
23835         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23836
23837         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23838         [ $stripe_count -eq 0 ] ||
23839                         error "expect 0 get $stripe_count for a"
23840
23841         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23842                 error "set default stripes dir error"
23843
23844         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23845
23846         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23847         [ $stripe_count -eq 0 ] ||
23848                         error "expect 0 get $stripe_count for b"
23849
23850         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23851                 error "set default stripes dir error"
23852
23853         mkdir $DIR/$tdir/striped_dir/c &&
23854                 error "default stripe_index is invalid, mkdir c should fails"
23855
23856         rm -rf $DIR/$tdir || error "rmdir fails"
23857 }
23858 run_test 300m "setstriped directory on single MDT FS"
23859
23860 cleanup_300n() {
23861         local list=$(comma_list $(mdts_nodes))
23862
23863         trap 0
23864         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23865 }
23866
23867 test_300n() {
23868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23869         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23870         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23871                 skip "Need MDS version at least 2.7.55"
23872         remote_mds_nodsh && skip "remote MDS with nodsh"
23873
23874         local stripe_index
23875         local list=$(comma_list $(mdts_nodes))
23876
23877         trap cleanup_300n RETURN EXIT
23878         mkdir -p $DIR/$tdir
23879         chmod 777 $DIR/$tdir
23880         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23881                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23882                 error "create striped dir succeeds with gid=0"
23883
23884         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23885         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23886                 error "create striped dir fails with gid=-1"
23887
23888         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23889         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23890                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23891                 error "set default striped dir succeeds with gid=0"
23892
23893
23894         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23895         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23896                 error "set default striped dir fails with gid=-1"
23897
23898
23899         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23900         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23901                                         error "create test_dir fails"
23902         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23903                                         error "create test_dir1 fails"
23904         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23905                                         error "create test_dir2 fails"
23906         cleanup_300n
23907 }
23908 run_test 300n "non-root user to create dir under striped dir with default EA"
23909
23910 test_300o() {
23911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23912         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23913         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23914                 skip "Need MDS version at least 2.7.55"
23915
23916         local numfree1
23917         local numfree2
23918
23919         mkdir -p $DIR/$tdir
23920
23921         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23922         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23923         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23924                 skip "not enough free inodes $numfree1 $numfree2"
23925         fi
23926
23927         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23928         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23929         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23930                 skip "not enough free space $numfree1 $numfree2"
23931         fi
23932
23933         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23934                 error "setdirstripe fails"
23935
23936         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23937                 error "create dirs fails"
23938
23939         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23940         ls $DIR/$tdir/striped_dir > /dev/null ||
23941                 error "ls striped dir fails"
23942         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23943                 error "unlink big striped dir fails"
23944 }
23945 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23946
23947 test_300p() {
23948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23949         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23950         remote_mds_nodsh && skip "remote MDS with nodsh"
23951
23952         mkdir_on_mdt0 $DIR/$tdir
23953
23954         #define OBD_FAIL_OUT_ENOSPC     0x1704
23955         do_facet mds2 lctl set_param fail_loc=0x80001704
23956         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23957                  && error "create striped directory should fail"
23958
23959         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23960
23961         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23962         true
23963 }
23964 run_test 300p "create striped directory without space"
23965
23966 test_300q() {
23967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23968         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23969
23970         local fd=$(free_fd)
23971         local cmd="exec $fd<$tdir"
23972         cd $DIR
23973         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23974         eval $cmd
23975         cmd="exec $fd<&-"
23976         trap "eval $cmd" EXIT
23977         cd $tdir || error "cd $tdir fails"
23978         rmdir  ../$tdir || error "rmdir $tdir fails"
23979         mkdir local_dir && error "create dir succeeds"
23980         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23981         eval $cmd
23982         return 0
23983 }
23984 run_test 300q "create remote directory under orphan directory"
23985
23986 test_300r() {
23987         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23988                 skip "Need MDS version at least 2.7.55" && return
23989         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23990
23991         mkdir $DIR/$tdir
23992
23993         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23994                 error "set striped dir error"
23995
23996         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23997                 error "getstripeddir fails"
23998
23999         local stripe_count
24000         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24001                       awk '/lmv_stripe_count:/ { print $2 }')
24002
24003         [ $MDSCOUNT -ne $stripe_count ] &&
24004                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24005
24006         rm -rf $DIR/$tdir/striped_dir ||
24007                 error "unlink striped dir fails"
24008 }
24009 run_test 300r "test -1 striped directory"
24010
24011 test_300s_helper() {
24012         local count=$1
24013
24014         local stripe_dir=$DIR/$tdir/striped_dir.$count
24015
24016         $LFS mkdir -c $count $stripe_dir ||
24017                 error "lfs mkdir -c error"
24018
24019         $LFS getdirstripe $stripe_dir ||
24020                 error "lfs getdirstripe fails"
24021
24022         local stripe_count
24023         stripe_count=$($LFS getdirstripe $stripe_dir |
24024                       awk '/lmv_stripe_count:/ { print $2 }')
24025
24026         [ $count -ne $stripe_count ] &&
24027                 error_noexit "bad stripe count $stripe_count expected $count"
24028
24029         local dupe_stripes
24030         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24031                 awk '/0x/ {count[$1] += 1}; END {
24032                         for (idx in count) {
24033                                 if (count[idx]>1) {
24034                                         print "index " idx " count " count[idx]
24035                                 }
24036                         }
24037                 }')
24038
24039         if [[ -n "$dupe_stripes" ]] ; then
24040                 lfs getdirstripe $stripe_dir
24041                 error_noexit "Dupe MDT above: $dupe_stripes "
24042         fi
24043
24044         rm -rf $stripe_dir ||
24045                 error_noexit "unlink $stripe_dir fails"
24046 }
24047
24048 test_300s() {
24049         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24050                 skip "Need MDS version at least 2.7.55" && return
24051         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24052
24053         mkdir $DIR/$tdir
24054         for count in $(seq 2 $MDSCOUNT); do
24055                 test_300s_helper $count
24056         done
24057 }
24058 run_test 300s "test lfs mkdir -c without -i"
24059
24060 test_300t() {
24061         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24062                 skip "need MDS 2.14.55 or later"
24063         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24064
24065         local testdir="$DIR/$tdir/striped_dir"
24066         local dir1=$testdir/dir1
24067         local dir2=$testdir/dir2
24068
24069         mkdir -p $testdir
24070
24071         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24072                 error "failed to set default stripe count for $testdir"
24073
24074         mkdir $dir1
24075         local stripe_count=$($LFS getdirstripe -c $dir1)
24076
24077         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24078
24079         local max_count=$((MDSCOUNT - 1))
24080         local mdts=$(comma_list $(mdts_nodes))
24081
24082         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24083         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24084
24085         mkdir $dir2
24086         stripe_count=$($LFS getdirstripe -c $dir2)
24087
24088         (( $stripe_count == $max_count )) || error "wrong stripe count"
24089 }
24090 run_test 300t "test max_mdt_stripecount"
24091
24092 prepare_remote_file() {
24093         mkdir $DIR/$tdir/src_dir ||
24094                 error "create remote source failed"
24095
24096         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24097                  error "cp to remote source failed"
24098         touch $DIR/$tdir/src_dir/a
24099
24100         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24101                 error "create remote target dir failed"
24102
24103         touch $DIR/$tdir/tgt_dir/b
24104
24105         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24106                 error "rename dir cross MDT failed!"
24107
24108         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24109                 error "src_child still exists after rename"
24110
24111         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24112                 error "missing file(a) after rename"
24113
24114         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24115                 error "diff after rename"
24116 }
24117
24118 test_310a() {
24119         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24121
24122         local remote_file=$DIR/$tdir/tgt_dir/b
24123
24124         mkdir -p $DIR/$tdir
24125
24126         prepare_remote_file || error "prepare remote file failed"
24127
24128         #open-unlink file
24129         $OPENUNLINK $remote_file $remote_file ||
24130                 error "openunlink $remote_file failed"
24131         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24132 }
24133 run_test 310a "open unlink remote file"
24134
24135 test_310b() {
24136         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24138
24139         local remote_file=$DIR/$tdir/tgt_dir/b
24140
24141         mkdir -p $DIR/$tdir
24142
24143         prepare_remote_file || error "prepare remote file failed"
24144
24145         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24146         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24147         $CHECKSTAT -t file $remote_file || error "check file failed"
24148 }
24149 run_test 310b "unlink remote file with multiple links while open"
24150
24151 test_310c() {
24152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24153         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24154
24155         local remote_file=$DIR/$tdir/tgt_dir/b
24156
24157         mkdir -p $DIR/$tdir
24158
24159         prepare_remote_file || error "prepare remote file failed"
24160
24161         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24162         multiop_bg_pause $remote_file O_uc ||
24163                         error "mulitop failed for remote file"
24164         MULTIPID=$!
24165         $MULTIOP $DIR/$tfile Ouc
24166         kill -USR1 $MULTIPID
24167         wait $MULTIPID
24168 }
24169 run_test 310c "open-unlink remote file with multiple links"
24170
24171 #LU-4825
24172 test_311() {
24173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24174         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24175         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24176                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24177         remote_mds_nodsh && skip "remote MDS with nodsh"
24178
24179         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24180         local mdts=$(comma_list $(mdts_nodes))
24181
24182         mkdir -p $DIR/$tdir
24183         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24184         createmany -o $DIR/$tdir/$tfile. 1000
24185
24186         # statfs data is not real time, let's just calculate it
24187         old_iused=$((old_iused + 1000))
24188
24189         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24190                         osp.*OST0000*MDT0000.create_count")
24191         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24192                                 osp.*OST0000*MDT0000.max_create_count")
24193         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24194
24195         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24196         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24197         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24198
24199         unlinkmany $DIR/$tdir/$tfile. 1000
24200
24201         do_nodes $mdts "$LCTL set_param -n \
24202                         osp.*OST0000*.max_create_count=$max_count"
24203         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24204                 do_nodes $mdts "$LCTL set_param -n \
24205                                 osp.*OST0000*.create_count=$count"
24206         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24207                         grep "=0" && error "create_count is zero"
24208
24209         local new_iused
24210         for i in $(seq 120); do
24211                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24212                 # system may be too busy to destroy all objs in time, use
24213                 # a somewhat small value to not fail autotest
24214                 [ $((old_iused - new_iused)) -gt 400 ] && break
24215                 sleep 1
24216         done
24217
24218         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24219         [ $((old_iused - new_iused)) -gt 400 ] ||
24220                 error "objs not destroyed after unlink"
24221 }
24222 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24223
24224 zfs_oid_to_objid()
24225 {
24226         local ost=$1
24227         local objid=$2
24228
24229         local vdevdir=$(dirname $(facet_vdevice $ost))
24230         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24231         local zfs_zapid=$(do_facet $ost $cmd |
24232                           grep -w "/O/0/d$((objid%32))" -C 5 |
24233                           awk '/Object/{getline; print $1}')
24234         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24235                           awk "/$objid = /"'{printf $3}')
24236
24237         echo $zfs_objid
24238 }
24239
24240 zfs_object_blksz() {
24241         local ost=$1
24242         local objid=$2
24243
24244         local vdevdir=$(dirname $(facet_vdevice $ost))
24245         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24246         local blksz=$(do_facet $ost $cmd $objid |
24247                       awk '/dblk/{getline; printf $4}')
24248
24249         case "${blksz: -1}" in
24250                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24251                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24252                 *) ;;
24253         esac
24254
24255         echo $blksz
24256 }
24257
24258 test_312() { # LU-4856
24259         remote_ost_nodsh && skip "remote OST with nodsh"
24260         [ "$ost1_FSTYPE" = "zfs" ] ||
24261                 skip_env "the test only applies to zfs"
24262
24263         local max_blksz=$(do_facet ost1 \
24264                           $ZFS get -p recordsize $(facet_device ost1) |
24265                           awk '!/VALUE/{print $3}')
24266
24267         # to make life a little bit easier
24268         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24269         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24270
24271         local tf=$DIR/$tdir/$tfile
24272         touch $tf
24273         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24274
24275         # Get ZFS object id
24276         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24277         # block size change by sequential overwrite
24278         local bs
24279
24280         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24281                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24282
24283                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24284                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24285         done
24286         rm -f $tf
24287
24288         # block size change by sequential append write
24289         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24290         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24291         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24292         local count
24293
24294         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24295                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24296                         oflag=sync conv=notrunc
24297
24298                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24299                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24300                         error "blksz error, actual $blksz, " \
24301                                 "expected: 2 * $count * $PAGE_SIZE"
24302         done
24303         rm -f $tf
24304
24305         # random write
24306         touch $tf
24307         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24308         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24309
24310         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24311         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24312         [ $blksz -eq $PAGE_SIZE ] ||
24313                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24314
24315         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24316         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24317         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24318
24319         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24320         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24321         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24322 }
24323 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24324
24325 test_313() {
24326         remote_ost_nodsh && skip "remote OST with nodsh"
24327
24328         local file=$DIR/$tfile
24329
24330         rm -f $file
24331         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24332
24333         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24334         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24335         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24336                 error "write should failed"
24337         do_facet ost1 "$LCTL set_param fail_loc=0"
24338         rm -f $file
24339 }
24340 run_test 313 "io should fail after last_rcvd update fail"
24341
24342 test_314() {
24343         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24344
24345         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24346         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24347         rm -f $DIR/$tfile
24348         wait_delete_completed
24349         do_facet ost1 "$LCTL set_param fail_loc=0"
24350 }
24351 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24352
24353 test_315() { # LU-618
24354         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24355
24356         local file=$DIR/$tfile
24357         rm -f $file
24358
24359         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24360                 error "multiop file write failed"
24361         $MULTIOP $file oO_RDONLY:r4063232_c &
24362         PID=$!
24363
24364         sleep 2
24365
24366         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24367         kill -USR1 $PID
24368
24369         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24370         rm -f $file
24371 }
24372 run_test 315 "read should be accounted"
24373
24374 test_316() {
24375         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24376         large_xattr_enabled || skip "ea_inode feature disabled"
24377
24378         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24379         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24380         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24381         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24382
24383         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24384 }
24385 run_test 316 "lfs migrate of file with large_xattr enabled"
24386
24387 test_317() {
24388         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24389                 skip "Need MDS version at least 2.11.53"
24390         if [ "$ost1_FSTYPE" == "zfs" ]; then
24391                 skip "LU-10370: no implementation for ZFS"
24392         fi
24393
24394         local trunc_sz
24395         local grant_blk_size
24396
24397         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24398                         awk '/grant_block_size:/ { print $2; exit; }')
24399         #
24400         # Create File of size 5M. Truncate it to below size's and verify
24401         # blocks count.
24402         #
24403         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24404                 error "Create file $DIR/$tfile failed"
24405         stack_trap "rm -f $DIR/$tfile" EXIT
24406
24407         for trunc_sz in 2097152 4097 4000 509 0; do
24408                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24409                         error "truncate $tfile to $trunc_sz failed"
24410                 local sz=$(stat --format=%s $DIR/$tfile)
24411                 local blk=$(stat --format=%b $DIR/$tfile)
24412                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24413                                      grant_blk_size) * 8))
24414
24415                 if [[ $blk -ne $trunc_blk ]]; then
24416                         $(which stat) $DIR/$tfile
24417                         error "Expected Block $trunc_blk got $blk for $tfile"
24418                 fi
24419
24420                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24421                         error "Expected Size $trunc_sz got $sz for $tfile"
24422         done
24423
24424         #
24425         # sparse file test
24426         # Create file with a hole and write actual 65536 bytes which aligned
24427         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24428         #
24429         local bs=65536
24430         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24431                 error "Create file : $DIR/$tfile"
24432
24433         #
24434         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24435         # blocks. The block count must drop to 8.
24436         #
24437         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24438                 ((bs - grant_blk_size) + 1)))
24439         $TRUNCATE $DIR/$tfile $trunc_sz ||
24440                 error "truncate $tfile to $trunc_sz failed"
24441
24442         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24443         sz=$(stat --format=%s $DIR/$tfile)
24444         blk=$(stat --format=%b $DIR/$tfile)
24445
24446         if [[ $blk -ne $trunc_bsz ]]; then
24447                 $(which stat) $DIR/$tfile
24448                 error "Expected Block $trunc_bsz got $blk for $tfile"
24449         fi
24450
24451         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24452                 error "Expected Size $trunc_sz got $sz for $tfile"
24453 }
24454 run_test 317 "Verify blocks get correctly update after truncate"
24455
24456 test_318() {
24457         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24458         local old_max_active=$($LCTL get_param -n \
24459                             ${llite_name}.max_read_ahead_async_active \
24460                             2>/dev/null)
24461
24462         $LCTL set_param llite.*.max_read_ahead_async_active=256
24463         local max_active=$($LCTL get_param -n \
24464                            ${llite_name}.max_read_ahead_async_active \
24465                            2>/dev/null)
24466         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24467
24468         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24469                 error "set max_read_ahead_async_active should succeed"
24470
24471         $LCTL set_param llite.*.max_read_ahead_async_active=512
24472         max_active=$($LCTL get_param -n \
24473                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24474         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24475
24476         # restore @max_active
24477         [ $old_max_active -ne 0 ] && $LCTL set_param \
24478                 llite.*.max_read_ahead_async_active=$old_max_active
24479
24480         local old_threshold=$($LCTL get_param -n \
24481                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24482         local max_per_file_mb=$($LCTL get_param -n \
24483                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24484
24485         local invalid=$(($max_per_file_mb + 1))
24486         $LCTL set_param \
24487                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24488                         && error "set $invalid should fail"
24489
24490         local valid=$(($invalid - 1))
24491         $LCTL set_param \
24492                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24493                         error "set $valid should succeed"
24494         local threshold=$($LCTL get_param -n \
24495                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24496         [ $threshold -eq $valid ] || error \
24497                 "expect threshold $valid got $threshold"
24498         $LCTL set_param \
24499                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24500 }
24501 run_test 318 "Verify async readahead tunables"
24502
24503 test_319() {
24504         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24505
24506         local before=$(date +%s)
24507         local evict
24508         local mdir=$DIR/$tdir
24509         local file=$mdir/xxx
24510
24511         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24512         touch $file
24513
24514 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24515         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24516         $LFS migrate -m1 $mdir &
24517
24518         sleep 1
24519         dd if=$file of=/dev/null
24520         wait
24521         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24522           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24523
24524         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24525 }
24526 run_test 319 "lost lease lock on migrate error"
24527
24528 test_398a() { # LU-4198
24529         local ost1_imp=$(get_osc_import_name client ost1)
24530         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24531                          cut -d'.' -f2)
24532
24533         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24534         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24535
24536         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24537         # request a new lock on client
24538         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24539
24540         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24541         #local lock_count=$($LCTL get_param -n \
24542         #                  ldlm.namespaces.$imp_name.lru_size)
24543         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24544
24545         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24546
24547         # no lock cached, should use lockless DIO and not enqueue new lock
24548         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24549                 conv=notrunc ||
24550                 error "dio write failed"
24551         lock_count=$($LCTL get_param -n \
24552                      ldlm.namespaces.$imp_name.lru_size)
24553         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24554
24555         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24556
24557         # no lock cached, should use locked DIO append
24558         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24559                 conv=notrunc || error "DIO append failed"
24560         lock_count=$($LCTL get_param -n \
24561                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24562         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24563 }
24564 run_test 398a "direct IO should cancel lock otherwise lockless"
24565
24566 test_398b() { # LU-4198
24567         which fio || skip_env "no fio installed"
24568         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24569
24570         local size=48
24571         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24572
24573         local njobs=4
24574         # Single page, multiple pages, stripe size, 4*stripe size
24575         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24576                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24577                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24578                         --numjobs=$njobs --fallocate=none \
24579                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24580                         --filename=$DIR/$tfile &
24581                 bg_pid=$!
24582
24583                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24584                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24585                         --numjobs=$njobs --fallocate=none \
24586                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24587                         --filename=$DIR/$tfile || true
24588                 wait $bg_pid
24589         done
24590
24591         evict=$(do_facet client $LCTL get_param \
24592                 osc.$FSNAME-OST*-osc-*/state |
24593             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24594
24595         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24596                 (do_facet client $LCTL get_param \
24597                         osc.$FSNAME-OST*-osc-*/state;
24598                     error "eviction happened: $evict before:$before")
24599
24600         rm -f $DIR/$tfile
24601 }
24602 run_test 398b "DIO and buffer IO race"
24603
24604 test_398c() { # LU-4198
24605         local ost1_imp=$(get_osc_import_name client ost1)
24606         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24607                          cut -d'.' -f2)
24608
24609         which fio || skip_env "no fio installed"
24610
24611         saved_debug=$($LCTL get_param -n debug)
24612         $LCTL set_param debug=0
24613
24614         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24615         ((size /= 1024)) # by megabytes
24616         ((size /= 2)) # write half of the OST at most
24617         [ $size -gt 40 ] && size=40 #reduce test time anyway
24618
24619         $LFS setstripe -c 1 $DIR/$tfile
24620
24621         # it seems like ldiskfs reserves more space than necessary if the
24622         # writing blocks are not mapped, so it extends the file firstly
24623         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24624         cancel_lru_locks osc
24625
24626         # clear and verify rpc_stats later
24627         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24628
24629         local njobs=4
24630         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24631         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24632                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24633                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24634                 --filename=$DIR/$tfile
24635         [ $? -eq 0 ] || error "fio write error"
24636
24637         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24638                 error "Locks were requested while doing AIO"
24639
24640         # get the percentage of 1-page I/O
24641         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24642                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24643                 awk '{print $7}')
24644         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24645
24646         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24647         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24648                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24649                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24650                 --filename=$DIR/$tfile
24651         [ $? -eq 0 ] || error "fio mixed read write error"
24652
24653         echo "AIO with large block size ${size}M"
24654         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24655                 --numjobs=1 --fallocate=none --ioengine=libaio \
24656                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24657                 --filename=$DIR/$tfile
24658         [ $? -eq 0 ] || error "fio large block size failed"
24659
24660         rm -f $DIR/$tfile
24661         $LCTL set_param debug="$saved_debug"
24662 }
24663 run_test 398c "run fio to test AIO"
24664
24665 test_398d() { #  LU-13846
24666         which aiocp || skip_env "no aiocp installed"
24667         local aio_file=$DIR/$tfile.aio
24668
24669         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24670
24671         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24672         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24673         stack_trap "rm -f $DIR/$tfile $aio_file"
24674
24675         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24676
24677         # make sure we don't crash and fail properly
24678         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24679                 error "aio not aligned with PAGE SIZE should fail"
24680
24681         rm -f $DIR/$tfile $aio_file
24682 }
24683 run_test 398d "run aiocp to verify block size > stripe size"
24684
24685 test_398e() {
24686         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24687         touch $DIR/$tfile.new
24688         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24689 }
24690 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24691
24692 test_398f() { #  LU-14687
24693         which aiocp || skip_env "no aiocp installed"
24694         local aio_file=$DIR/$tfile.aio
24695
24696         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24697
24698         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24699         stack_trap "rm -f $DIR/$tfile $aio_file"
24700
24701         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24702         $LCTL set_param fail_loc=0x1418
24703         # make sure we don't crash and fail properly
24704         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24705                 error "aio with page allocation failure succeeded"
24706         $LCTL set_param fail_loc=0
24707         diff $DIR/$tfile $aio_file
24708         [[ $? != 0 ]] || error "no diff after failed aiocp"
24709 }
24710 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24711
24712 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24713 # stripe and i/o size must be > stripe size
24714 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24715 # single RPC in flight.  This test shows async DIO submission is working by
24716 # showing multiple RPCs in flight.
24717 test_398g() { #  LU-13798
24718         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24719
24720         # We need to do some i/o first to acquire enough grant to put our RPCs
24721         # in flight; otherwise a new connection may not have enough grant
24722         # available
24723         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24724                 error "parallel dio failed"
24725         stack_trap "rm -f $DIR/$tfile"
24726
24727         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24728         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24729         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24730         stack_trap "$LCTL set_param -n $pages_per_rpc"
24731
24732         # Recreate file so it's empty
24733         rm -f $DIR/$tfile
24734         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24735         #Pause rpc completion to guarantee we see multiple rpcs in flight
24736         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24737         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24738         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24739
24740         # Clear rpc stats
24741         $LCTL set_param osc.*.rpc_stats=c
24742
24743         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24744                 error "parallel dio failed"
24745         stack_trap "rm -f $DIR/$tfile"
24746
24747         $LCTL get_param osc.*-OST0000-*.rpc_stats
24748         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24749                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24750                 grep "8:" | awk '{print $8}')
24751         # We look at the "8 rpcs in flight" field, and verify A) it is present
24752         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24753         # as expected for an 8M DIO to a file with 1M stripes.
24754         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24755
24756         # Verify turning off parallel dio works as expected
24757         # Clear rpc stats
24758         $LCTL set_param osc.*.rpc_stats=c
24759         $LCTL set_param llite.*.parallel_dio=0
24760         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24761
24762         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24763                 error "dio with parallel dio disabled failed"
24764
24765         # Ideally, we would see only one RPC in flight here, but there is an
24766         # unavoidable race between i/o completion and RPC in flight counting,
24767         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24768         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24769         # So instead we just verify it's always < 8.
24770         $LCTL get_param osc.*-OST0000-*.rpc_stats
24771         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24772                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24773                 grep '^$' -B1 | grep . | awk '{print $1}')
24774         [ $ret != "8:" ] ||
24775                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24776 }
24777 run_test 398g "verify parallel dio async RPC submission"
24778
24779 test_398h() { #  LU-13798
24780         local dio_file=$DIR/$tfile.dio
24781
24782         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24783
24784         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24785         stack_trap "rm -f $DIR/$tfile $dio_file"
24786
24787         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24788                 error "parallel dio failed"
24789         diff $DIR/$tfile $dio_file
24790         [[ $? == 0 ]] || error "file diff after aiocp"
24791 }
24792 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24793
24794 test_398i() { #  LU-13798
24795         local dio_file=$DIR/$tfile.dio
24796
24797         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24798
24799         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24800         stack_trap "rm -f $DIR/$tfile $dio_file"
24801
24802         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24803         $LCTL set_param fail_loc=0x1418
24804         # make sure we don't crash and fail properly
24805         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24806                 error "parallel dio page allocation failure succeeded"
24807         diff $DIR/$tfile $dio_file
24808         [[ $? != 0 ]] || error "no diff after failed aiocp"
24809 }
24810 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24811
24812 test_398j() { #  LU-13798
24813         # Stripe size > RPC size but less than i/o size tests split across
24814         # stripes and RPCs for individual i/o op
24815         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24816
24817         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24818         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24819         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24820         stack_trap "$LCTL set_param -n $pages_per_rpc"
24821
24822         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24823                 error "parallel dio write failed"
24824         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24825
24826         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24827                 error "parallel dio read failed"
24828         diff $DIR/$tfile $DIR/$tfile.2
24829         [[ $? == 0 ]] || error "file diff after parallel dio read"
24830 }
24831 run_test 398j "test parallel dio where stripe size > rpc_size"
24832
24833 test_398k() { #  LU-13798
24834         wait_delete_completed
24835         wait_mds_ost_sync
24836
24837         # 4 stripe file; we will cause out of space on OST0
24838         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24839
24840         # Fill OST0 (if it's not too large)
24841         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24842                    head -n1)
24843         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24844                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24845         fi
24846         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24847         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24848                 error "dd should fill OST0"
24849         stack_trap "rm -f $DIR/$tfile.1"
24850
24851         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24852         err=$?
24853
24854         ls -la $DIR/$tfile
24855         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24856                 error "file is not 0 bytes in size"
24857
24858         # dd above should not succeed, but don't error until here so we can
24859         # get debug info above
24860         [[ $err != 0 ]] ||
24861                 error "parallel dio write with enospc succeeded"
24862         stack_trap "rm -f $DIR/$tfile"
24863 }
24864 run_test 398k "test enospc on first stripe"
24865
24866 test_398l() { #  LU-13798
24867         wait_delete_completed
24868         wait_mds_ost_sync
24869
24870         # 4 stripe file; we will cause out of space on OST0
24871         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24872         # happens on the second i/o chunk we issue
24873         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24874
24875         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24876         stack_trap "rm -f $DIR/$tfile"
24877
24878         # Fill OST0 (if it's not too large)
24879         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24880                    head -n1)
24881         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24882                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24883         fi
24884         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24885         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24886                 error "dd should fill OST0"
24887         stack_trap "rm -f $DIR/$tfile.1"
24888
24889         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24890         err=$?
24891         stack_trap "rm -f $DIR/$tfile.2"
24892
24893         # Check that short write completed as expected
24894         ls -la $DIR/$tfile.2
24895         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24896                 error "file is not 1M in size"
24897
24898         # dd above should not succeed, but don't error until here so we can
24899         # get debug info above
24900         [[ $err != 0 ]] ||
24901                 error "parallel dio write with enospc succeeded"
24902
24903         # Truncate source file to same length as output file and diff them
24904         $TRUNCATE $DIR/$tfile 1048576
24905         diff $DIR/$tfile $DIR/$tfile.2
24906         [[ $? == 0 ]] || error "data incorrect after short write"
24907 }
24908 run_test 398l "test enospc on intermediate stripe/RPC"
24909
24910 test_398m() { #  LU-13798
24911         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24912
24913         # Set up failure on OST0, the first stripe:
24914         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24915         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24916         # So this fail_val specifies OST0
24917         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24918         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24919
24920         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24921                 error "parallel dio write with failure on first stripe succeeded"
24922         stack_trap "rm -f $DIR/$tfile"
24923         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24924
24925         # Place data in file for read
24926         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24927                 error "parallel dio write failed"
24928
24929         # Fail read on OST0, first stripe
24930         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24931         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24932         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24933                 error "parallel dio read with error on first stripe succeeded"
24934         rm -f $DIR/$tfile.2
24935         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24936
24937         # Switch to testing on OST1, second stripe
24938         # Clear file contents, maintain striping
24939         echo > $DIR/$tfile
24940         # Set up failure on OST1, second stripe:
24941         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24942         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24943
24944         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24945                 error "parallel dio write with failure on first stripe succeeded"
24946         stack_trap "rm -f $DIR/$tfile"
24947         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24948
24949         # Place data in file for read
24950         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24951                 error "parallel dio write failed"
24952
24953         # Fail read on OST1, second stripe
24954         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24955         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24956         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24957                 error "parallel dio read with error on first stripe succeeded"
24958         rm -f $DIR/$tfile.2
24959         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24960 }
24961 run_test 398m "test RPC failures with parallel dio"
24962
24963 # Parallel submission of DIO should not cause problems for append, but it's
24964 # important to verify.
24965 test_398n() { #  LU-13798
24966         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24967
24968         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24969                 error "dd to create source file failed"
24970         stack_trap "rm -f $DIR/$tfile"
24971
24972         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24973                 error "parallel dio write with failure on second stripe succeeded"
24974         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24975         diff $DIR/$tfile $DIR/$tfile.1
24976         [[ $? == 0 ]] || error "data incorrect after append"
24977
24978 }
24979 run_test 398n "test append with parallel DIO"
24980
24981 test_fake_rw() {
24982         local read_write=$1
24983         if [ "$read_write" = "write" ]; then
24984                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24985         elif [ "$read_write" = "read" ]; then
24986                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24987         else
24988                 error "argument error"
24989         fi
24990
24991         # turn off debug for performance testing
24992         local saved_debug=$($LCTL get_param -n debug)
24993         $LCTL set_param debug=0
24994
24995         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24996
24997         # get ost1 size - $FSNAME-OST0000
24998         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24999         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25000         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25001
25002         if [ "$read_write" = "read" ]; then
25003                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25004         fi
25005
25006         local start_time=$(date +%s.%N)
25007         $dd_cmd bs=1M count=$blocks oflag=sync ||
25008                 error "real dd $read_write error"
25009         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25010
25011         if [ "$read_write" = "write" ]; then
25012                 rm -f $DIR/$tfile
25013         fi
25014
25015         # define OBD_FAIL_OST_FAKE_RW           0x238
25016         do_facet ost1 $LCTL set_param fail_loc=0x238
25017
25018         local start_time=$(date +%s.%N)
25019         $dd_cmd bs=1M count=$blocks oflag=sync ||
25020                 error "fake dd $read_write error"
25021         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25022
25023         if [ "$read_write" = "write" ]; then
25024                 # verify file size
25025                 cancel_lru_locks osc
25026                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25027                         error "$tfile size not $blocks MB"
25028         fi
25029         do_facet ost1 $LCTL set_param fail_loc=0
25030
25031         echo "fake $read_write $duration_fake vs. normal $read_write" \
25032                 "$duration in seconds"
25033         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25034                 error_not_in_vm "fake write is slower"
25035
25036         $LCTL set_param -n debug="$saved_debug"
25037         rm -f $DIR/$tfile
25038 }
25039 test_399a() { # LU-7655 for OST fake write
25040         remote_ost_nodsh && skip "remote OST with nodsh"
25041
25042         test_fake_rw write
25043 }
25044 run_test 399a "fake write should not be slower than normal write"
25045
25046 test_399b() { # LU-8726 for OST fake read
25047         remote_ost_nodsh && skip "remote OST with nodsh"
25048         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25049                 skip_env "ldiskfs only test"
25050         fi
25051
25052         test_fake_rw read
25053 }
25054 run_test 399b "fake read should not be slower than normal read"
25055
25056 test_400a() { # LU-1606, was conf-sanity test_74
25057         if ! which $CC > /dev/null 2>&1; then
25058                 skip_env "$CC is not installed"
25059         fi
25060
25061         local extra_flags=''
25062         local out=$TMP/$tfile
25063         local prefix=/usr/include/lustre
25064         local prog
25065
25066         # Oleg removes c files in his test rig so test if any c files exist
25067         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25068                 skip_env "Needed c test files are missing"
25069
25070         if ! [[ -d $prefix ]]; then
25071                 # Assume we're running in tree and fixup the include path.
25072                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25073                 extra_flags+=" -L$LUSTRE/utils/.lib"
25074         fi
25075
25076         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25077                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25078                         error "client api broken"
25079         done
25080         rm -f $out
25081 }
25082 run_test 400a "Lustre client api program can compile and link"
25083
25084 test_400b() { # LU-1606, LU-5011
25085         local header
25086         local out=$TMP/$tfile
25087         local prefix=/usr/include/linux/lustre
25088
25089         # We use a hard coded prefix so that this test will not fail
25090         # when run in tree. There are headers in lustre/include/lustre/
25091         # that are not packaged (like lustre_idl.h) and have more
25092         # complicated include dependencies (like config.h and lnet/types.h).
25093         # Since this test about correct packaging we just skip them when
25094         # they don't exist (see below) rather than try to fixup cppflags.
25095
25096         if ! which $CC > /dev/null 2>&1; then
25097                 skip_env "$CC is not installed"
25098         fi
25099
25100         for header in $prefix/*.h; do
25101                 if ! [[ -f "$header" ]]; then
25102                         continue
25103                 fi
25104
25105                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25106                         continue # lustre_ioctl.h is internal header
25107                 fi
25108
25109                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25110                         error "cannot compile '$header'"
25111         done
25112         rm -f $out
25113 }
25114 run_test 400b "packaged headers can be compiled"
25115
25116 test_401a() { #LU-7437
25117         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25118         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25119
25120         #count the number of parameters by "list_param -R"
25121         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25122         #count the number of parameters by listing proc files
25123         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25124         echo "proc_dirs='$proc_dirs'"
25125         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25126         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25127                       sort -u | wc -l)
25128
25129         [ $params -eq $procs ] ||
25130                 error "found $params parameters vs. $procs proc files"
25131
25132         # test the list_param -D option only returns directories
25133         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25134         #count the number of parameters by listing proc directories
25135         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25136                 sort -u | wc -l)
25137
25138         [ $params -eq $procs ] ||
25139                 error "found $params parameters vs. $procs proc files"
25140 }
25141 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25142
25143 test_401b() {
25144         # jobid_var may not allow arbitrary values, so use jobid_name
25145         # if available
25146         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25147                 local testname=jobid_name tmp='testing%p'
25148         else
25149                 local testname=jobid_var tmp=testing
25150         fi
25151
25152         local save=$($LCTL get_param -n $testname)
25153
25154         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25155                 error "no error returned when setting bad parameters"
25156
25157         local jobid_new=$($LCTL get_param -n foe $testname baz)
25158         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25159
25160         $LCTL set_param -n fog=bam $testname=$save bat=fog
25161         local jobid_old=$($LCTL get_param -n foe $testname bag)
25162         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25163 }
25164 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25165
25166 test_401c() {
25167         # jobid_var may not allow arbitrary values, so use jobid_name
25168         # if available
25169         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25170                 local testname=jobid_name
25171         else
25172                 local testname=jobid_var
25173         fi
25174
25175         local jobid_var_old=$($LCTL get_param -n $testname)
25176         local jobid_var_new
25177
25178         $LCTL set_param $testname= &&
25179                 error "no error returned for 'set_param a='"
25180
25181         jobid_var_new=$($LCTL get_param -n $testname)
25182         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25183                 error "$testname was changed by setting without value"
25184
25185         $LCTL set_param $testname &&
25186                 error "no error returned for 'set_param a'"
25187
25188         jobid_var_new=$($LCTL get_param -n $testname)
25189         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25190                 error "$testname was changed by setting without value"
25191 }
25192 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25193
25194 test_401d() {
25195         # jobid_var may not allow arbitrary values, so use jobid_name
25196         # if available
25197         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25198                 local testname=jobid_name new_value='foo=bar%p'
25199         else
25200                 local testname=jobid_var new_valuie=foo=bar
25201         fi
25202
25203         local jobid_var_old=$($LCTL get_param -n $testname)
25204         local jobid_var_new
25205
25206         $LCTL set_param $testname=$new_value ||
25207                 error "'set_param a=b' did not accept a value containing '='"
25208
25209         jobid_var_new=$($LCTL get_param -n $testname)
25210         [[ "$jobid_var_new" == "$new_value" ]] ||
25211                 error "'set_param a=b' failed on a value containing '='"
25212
25213         # Reset the $testname to test the other format
25214         $LCTL set_param $testname=$jobid_var_old
25215         jobid_var_new=$($LCTL get_param -n $testname)
25216         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25217                 error "failed to reset $testname"
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         $LCTL set_param $testname $jobid_var_old
25227         jobid_var_new=$($LCTL get_param -n $testname)
25228         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25229                 error "failed to reset $testname"
25230 }
25231 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25232
25233 test_401e() { # LU-14779
25234         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25235                 error "lctl list_param MGC* failed"
25236         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25237         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25238                 error "lctl get_param lru_size failed"
25239 }
25240 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25241
25242 test_402() {
25243         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25244         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25245                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25246         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25247                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25248                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25249         remote_mds_nodsh && skip "remote MDS with nodsh"
25250
25251         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25252 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25253         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25254         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25255                 echo "Touch failed - OK"
25256 }
25257 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25258
25259 test_403() {
25260         local file1=$DIR/$tfile.1
25261         local file2=$DIR/$tfile.2
25262         local tfile=$TMP/$tfile
25263
25264         rm -f $file1 $file2 $tfile
25265
25266         touch $file1
25267         ln $file1 $file2
25268
25269         # 30 sec OBD_TIMEOUT in ll_getattr()
25270         # right before populating st_nlink
25271         $LCTL set_param fail_loc=0x80001409
25272         stat -c %h $file1 > $tfile &
25273
25274         # create an alias, drop all locks and reclaim the dentry
25275         < $file2
25276         cancel_lru_locks mdc
25277         cancel_lru_locks osc
25278         sysctl -w vm.drop_caches=2
25279
25280         wait
25281
25282         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25283
25284         rm -f $tfile $file1 $file2
25285 }
25286 run_test 403 "i_nlink should not drop to zero due to aliasing"
25287
25288 test_404() { # LU-6601
25289         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25290                 skip "Need server version newer than 2.8.52"
25291         remote_mds_nodsh && skip "remote MDS with nodsh"
25292
25293         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25294                 awk '/osp .*-osc-MDT/ { print $4}')
25295
25296         local osp
25297         for osp in $mosps; do
25298                 echo "Deactivate: " $osp
25299                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25300                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25301                         awk -vp=$osp '$4 == p { print $2 }')
25302                 [ $stat = IN ] || {
25303                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25304                         error "deactivate error"
25305                 }
25306                 echo "Activate: " $osp
25307                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25308                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25309                         awk -vp=$osp '$4 == p { print $2 }')
25310                 [ $stat = UP ] || {
25311                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25312                         error "activate error"
25313                 }
25314         done
25315 }
25316 run_test 404 "validate manual {de}activated works properly for OSPs"
25317
25318 test_405() {
25319         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25320         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25321                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25322                         skip "Layout swap lock is not supported"
25323
25324         check_swap_layouts_support
25325         check_swap_layout_no_dom $DIR
25326
25327         test_mkdir $DIR/$tdir
25328         swap_lock_test -d $DIR/$tdir ||
25329                 error "One layout swap locked test failed"
25330 }
25331 run_test 405 "Various layout swap lock tests"
25332
25333 test_406() {
25334         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25335         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25336         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25338         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25339                 skip "Need MDS version at least 2.8.50"
25340
25341         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25342         local test_pool=$TESTNAME
25343
25344         pool_add $test_pool || error "pool_add failed"
25345         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25346                 error "pool_add_targets failed"
25347
25348         save_layout_restore_at_exit $MOUNT
25349
25350         # parent set default stripe count only, child will stripe from both
25351         # parent and fs default
25352         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25353                 error "setstripe $MOUNT failed"
25354         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25355         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25356         for i in $(seq 10); do
25357                 local f=$DIR/$tdir/$tfile.$i
25358                 touch $f || error "touch failed"
25359                 local count=$($LFS getstripe -c $f)
25360                 [ $count -eq $OSTCOUNT ] ||
25361                         error "$f stripe count $count != $OSTCOUNT"
25362                 local offset=$($LFS getstripe -i $f)
25363                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25364                 local size=$($LFS getstripe -S $f)
25365                 [ $size -eq $((def_stripe_size * 2)) ] ||
25366                         error "$f stripe size $size != $((def_stripe_size * 2))"
25367                 local pool=$($LFS getstripe -p $f)
25368                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25369         done
25370
25371         # change fs default striping, delete parent default striping, now child
25372         # will stripe from new fs default striping only
25373         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25374                 error "change $MOUNT default stripe failed"
25375         $LFS setstripe -c 0 $DIR/$tdir ||
25376                 error "delete $tdir default stripe failed"
25377         for i in $(seq 11 20); do
25378                 local f=$DIR/$tdir/$tfile.$i
25379                 touch $f || error "touch $f failed"
25380                 local count=$($LFS getstripe -c $f)
25381                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25382                 local offset=$($LFS getstripe -i $f)
25383                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25384                 local size=$($LFS getstripe -S $f)
25385                 [ $size -eq $def_stripe_size ] ||
25386                         error "$f stripe size $size != $def_stripe_size"
25387                 local pool=$($LFS getstripe -p $f)
25388                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25389         done
25390
25391         unlinkmany $DIR/$tdir/$tfile. 1 20
25392
25393         local f=$DIR/$tdir/$tfile
25394         pool_remove_all_targets $test_pool $f
25395         pool_remove $test_pool $f
25396 }
25397 run_test 406 "DNE support fs default striping"
25398
25399 test_407() {
25400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25401         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25402                 skip "Need MDS version at least 2.8.55"
25403         remote_mds_nodsh && skip "remote MDS with nodsh"
25404
25405         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25406                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25407         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25408                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25409         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25410
25411         #define OBD_FAIL_DT_TXN_STOP    0x2019
25412         for idx in $(seq $MDSCOUNT); do
25413                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25414         done
25415         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25416         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25417                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25418         true
25419 }
25420 run_test 407 "transaction fail should cause operation fail"
25421
25422 test_408() {
25423         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25424
25425         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25426         lctl set_param fail_loc=0x8000040a
25427         # let ll_prepare_partial_page() fail
25428         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25429
25430         rm -f $DIR/$tfile
25431
25432         # create at least 100 unused inodes so that
25433         # shrink_icache_memory(0) should not return 0
25434         touch $DIR/$tfile-{0..100}
25435         rm -f $DIR/$tfile-{0..100}
25436         sync
25437
25438         echo 2 > /proc/sys/vm/drop_caches
25439 }
25440 run_test 408 "drop_caches should not hang due to page leaks"
25441
25442 test_409()
25443 {
25444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25445
25446         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25447         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25448         touch $DIR/$tdir/guard || error "(2) Fail to create"
25449
25450         local PREFIX=$(str_repeat 'A' 128)
25451         echo "Create 1K hard links start at $(date)"
25452         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25453                 error "(3) Fail to hard link"
25454
25455         echo "Links count should be right although linkEA overflow"
25456         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25457         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25458         [ $linkcount -eq 1001 ] ||
25459                 error "(5) Unexpected hard links count: $linkcount"
25460
25461         echo "List all links start at $(date)"
25462         ls -l $DIR/$tdir/foo > /dev/null ||
25463                 error "(6) Fail to list $DIR/$tdir/foo"
25464
25465         echo "Unlink hard links start at $(date)"
25466         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25467                 error "(7) Fail to unlink"
25468         echo "Unlink hard links finished at $(date)"
25469 }
25470 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25471
25472 test_410()
25473 {
25474         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25475                 skip "Need client version at least 2.9.59"
25476         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25477                 skip "Need MODULES build"
25478
25479         # Create a file, and stat it from the kernel
25480         local testfile=$DIR/$tfile
25481         touch $testfile
25482
25483         local run_id=$RANDOM
25484         local my_ino=$(stat --format "%i" $testfile)
25485
25486         # Try to insert the module. This will always fail as the
25487         # module is designed to not be inserted.
25488         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25489             &> /dev/null
25490
25491         # Anything but success is a test failure
25492         dmesg | grep -q \
25493             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25494             error "no inode match"
25495 }
25496 run_test 410 "Test inode number returned from kernel thread"
25497
25498 cleanup_test411_cgroup() {
25499         trap 0
25500         rmdir "$1"
25501 }
25502
25503 test_411() {
25504         local cg_basedir=/sys/fs/cgroup/memory
25505         # LU-9966
25506         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25507                 skip "no setup for cgroup"
25508
25509         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25510                 error "test file creation failed"
25511         cancel_lru_locks osc
25512
25513         # Create a very small memory cgroup to force a slab allocation error
25514         local cgdir=$cg_basedir/osc_slab_alloc
25515         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25516         trap "cleanup_test411_cgroup $cgdir" EXIT
25517         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25518         echo 1M > $cgdir/memory.limit_in_bytes
25519
25520         # Should not LBUG, just be killed by oom-killer
25521         # dd will return 0 even allocation failure in some environment.
25522         # So don't check return value
25523         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25524         cleanup_test411_cgroup $cgdir
25525
25526         return 0
25527 }
25528 run_test 411 "Slab allocation error with cgroup does not LBUG"
25529
25530 test_412() {
25531         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25532         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25533                 skip "Need server version at least 2.10.55"
25534
25535         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25536                 error "mkdir failed"
25537         $LFS getdirstripe $DIR/$tdir
25538         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25539         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25540                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25541         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25542         [ $stripe_count -eq 2 ] ||
25543                 error "expect 2 get $stripe_count"
25544
25545         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25546
25547         local index
25548         local index2
25549
25550         # subdirs should be on the same MDT as parent
25551         for i in $(seq 0 $((MDSCOUNT - 1))); do
25552                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25553                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25554                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25555                 (( index == i )) || error "mdt$i/sub on MDT$index"
25556         done
25557
25558         # stripe offset -1, ditto
25559         for i in {1..10}; do
25560                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25561                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25562                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25563                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25564                 (( index == index2 )) ||
25565                         error "qos$i on MDT$index, sub on MDT$index2"
25566         done
25567
25568         local testdir=$DIR/$tdir/inherit
25569
25570         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25571         # inherit 2 levels
25572         for i in 1 2; do
25573                 testdir=$testdir/s$i
25574                 mkdir $testdir || error "mkdir $testdir failed"
25575                 index=$($LFS getstripe -m $testdir)
25576                 (( index == 1 )) ||
25577                         error "$testdir on MDT$index"
25578         done
25579
25580         # not inherit any more
25581         testdir=$testdir/s3
25582         mkdir $testdir || error "mkdir $testdir failed"
25583         getfattr -d -m dmv $testdir | grep dmv &&
25584                 error "default LMV set on $testdir" || true
25585 }
25586 run_test 412 "mkdir on specific MDTs"
25587
25588 generate_uneven_mdts() {
25589         local threshold=$1
25590         local lmv_qos_maxage
25591         local lod_qos_maxage
25592         local ffree
25593         local bavail
25594         local max
25595         local min
25596         local max_index
25597         local min_index
25598         local tmp
25599         local i
25600
25601         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25602         $LCTL set_param lmv.*.qos_maxage=1
25603         stack_trap "$LCTL set_param \
25604                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25605         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25606                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25607         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25608                 lod.*.mdt_qos_maxage=1
25609         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25610                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25611
25612         echo
25613         echo "Check for uneven MDTs: "
25614
25615         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25616         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25617         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25618
25619         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25620         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25621         max_index=0
25622         min_index=0
25623         for ((i = 1; i < ${#ffree[@]}; i++)); do
25624                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25625                 if [ $tmp -gt $max ]; then
25626                         max=$tmp
25627                         max_index=$i
25628                 fi
25629                 if [ $tmp -lt $min ]; then
25630                         min=$tmp
25631                         min_index=$i
25632                 fi
25633         done
25634
25635         (( ${ffree[min_index]} > 0 )) ||
25636                 skip "no free files in MDT$min_index"
25637         (( ${ffree[min_index]} < 10000000 )) ||
25638                 skip "too many free files in MDT$min_index"
25639
25640         # Check if we need to generate uneven MDTs
25641         local diff=$(((max - min) * 100 / min))
25642         local testdir=$DIR/$tdir-fillmdt
25643         local start
25644
25645         mkdir -p $testdir
25646
25647         i=0
25648         while (( diff < threshold )); do
25649                 # generate uneven MDTs, create till $threshold% diff
25650                 echo -n "weight diff=$diff% must be > $threshold% ..."
25651                 echo "Fill MDT$min_index with 1000 files: loop $i"
25652                 testdir=$DIR/$tdir-fillmdt/$i
25653                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25654                         error "mkdir $testdir failed"
25655                 $LFS setstripe -E 1M -L mdt $testdir ||
25656                         error "setstripe $testdir failed"
25657                 start=$SECONDS
25658                 for F in f.{0..999}; do
25659                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25660                                 /dev/null 2>&1 || error "dd $F failed"
25661                 done
25662
25663                 # wait for QOS to update
25664                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25665
25666                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25667                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25668                 max=$(((${ffree[max_index]} >> 8) *
25669                         (${bavail[max_index]} * bsize >> 16)))
25670                 min=$(((${ffree[min_index]} >> 8) *
25671                         (${bavail[min_index]} * bsize >> 16)))
25672                 diff=$(((max - min) * 100 / min))
25673                 i=$((i + 1))
25674         done
25675
25676         echo "MDT filesfree available: ${ffree[*]}"
25677         echo "MDT blocks available: ${bavail[*]}"
25678         echo "weight diff=$diff%"
25679 }
25680
25681 test_qos_mkdir() {
25682         local mkdir_cmd=$1
25683         local stripe_count=$2
25684         local mdts=$(comma_list $(mdts_nodes))
25685
25686         local testdir
25687         local lmv_qos_prio_free
25688         local lmv_qos_threshold_rr
25689         local lmv_qos_maxage
25690         local lod_qos_prio_free
25691         local lod_qos_threshold_rr
25692         local lod_qos_maxage
25693         local count
25694         local i
25695
25696         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25697         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25698         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25699                 head -n1)
25700         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25701         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25702         stack_trap "$LCTL set_param \
25703                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25704         stack_trap "$LCTL set_param \
25705                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25706         stack_trap "$LCTL set_param \
25707                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25708
25709         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25710                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25711         lod_qos_prio_free=${lod_qos_prio_free%%%}
25712         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25713                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25714         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25715         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25716                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25717         stack_trap "do_nodes $mdts $LCTL set_param \
25718                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25719         stack_trap "do_nodes $mdts $LCTL set_param \
25720                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25721         stack_trap "do_nodes $mdts $LCTL set_param \
25722                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25723
25724         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25725         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25726
25727         testdir=$DIR/$tdir-s$stripe_count/rr
25728
25729         local stripe_index=$($LFS getstripe -m $testdir)
25730         local test_mkdir_rr=true
25731
25732         getfattr -d -m dmv -e hex $testdir | grep dmv
25733         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25734                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25735                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25736                         test_mkdir_rr=false
25737         fi
25738
25739         echo
25740         $test_mkdir_rr &&
25741                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25742                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25743
25744         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25745         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25746                 eval $mkdir_cmd $testdir/subdir$i ||
25747                         error "$mkdir_cmd subdir$i failed"
25748         done
25749
25750         for (( i = 0; i < $MDSCOUNT; i++ )); do
25751                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25752                 echo "$count directories created on MDT$i"
25753                 if $test_mkdir_rr; then
25754                         (( $count == 100 )) ||
25755                                 error "subdirs are not evenly distributed"
25756                 elif (( $i == $stripe_index )); then
25757                         (( $count == 100 * MDSCOUNT )) ||
25758                                 error "$count subdirs created on MDT$i"
25759                 else
25760                         (( $count == 0 )) ||
25761                                 error "$count subdirs created on MDT$i"
25762                 fi
25763
25764                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25765                         count=$($LFS getdirstripe $testdir/* |
25766                                 grep -c -P "^\s+$i\t")
25767                         echo "$count stripes created on MDT$i"
25768                         # deviation should < 5% of average
25769                         (( $count >= 95 * stripe_count &&
25770                            $count <= 105 * stripe_count)) ||
25771                                 error "stripes are not evenly distributed"
25772                 fi
25773         done
25774
25775         echo
25776         echo "Check for uneven MDTs: "
25777
25778         local ffree
25779         local bavail
25780         local max
25781         local min
25782         local max_index
25783         local min_index
25784         local tmp
25785
25786         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25787         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25788         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25789
25790         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25791         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25792         max_index=0
25793         min_index=0
25794         for ((i = 1; i < ${#ffree[@]}; i++)); do
25795                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25796                 if [ $tmp -gt $max ]; then
25797                         max=$tmp
25798                         max_index=$i
25799                 fi
25800                 if [ $tmp -lt $min ]; then
25801                         min=$tmp
25802                         min_index=$i
25803                 fi
25804         done
25805
25806         (( ${ffree[min_index]} > 0 )) ||
25807                 skip "no free files in MDT$min_index"
25808         (( ${ffree[min_index]} < 10000000 )) ||
25809                 skip "too many free files in MDT$min_index"
25810
25811         echo "MDT filesfree available: ${ffree[*]}"
25812         echo "MDT blocks available: ${bavail[*]}"
25813         echo "weight diff=$(((max - min) * 100 / min))%"
25814         echo
25815         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25816
25817         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25818         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25819         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25820         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25821         # decrease statfs age, so that it can be updated in time
25822         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25823         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25824
25825         sleep 1
25826
25827         testdir=$DIR/$tdir-s$stripe_count/qos
25828         local num=200
25829
25830         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25831         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25832                 eval $mkdir_cmd $testdir/subdir$i ||
25833                         error "$mkdir_cmd subdir$i failed"
25834         done
25835
25836         max=0
25837         for (( i = 0; i < $MDSCOUNT; i++ )); do
25838                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25839                 (( count > max )) && max=$count
25840                 echo "$count directories created on MDT$i"
25841         done
25842
25843         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25844
25845         # D-value should > 10% of averge
25846         (( max - min > num / 10 )) ||
25847                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25848
25849         # ditto for stripes
25850         if (( stripe_count > 1 )); then
25851                 max=0
25852                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25853                         count=$($LFS getdirstripe $testdir/* |
25854                                 grep -c -P "^\s+$i\t")
25855                         (( count > max )) && max=$count
25856                         echo "$count stripes created on MDT$i"
25857                 done
25858
25859                 min=$($LFS getdirstripe $testdir/* |
25860                         grep -c -P "^\s+$min_index\t")
25861                 (( max - min > num * stripe_count / 10 )) ||
25862                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25863         fi
25864 }
25865
25866 most_full_mdt() {
25867         local ffree
25868         local bavail
25869         local bsize
25870         local min
25871         local min_index
25872         local tmp
25873
25874         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25875         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25876         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25877
25878         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25879         min_index=0
25880         for ((i = 1; i < ${#ffree[@]}; i++)); do
25881                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25882                 (( tmp < min )) && min=$tmp && min_index=$i
25883         done
25884
25885         echo -n $min_index
25886 }
25887
25888 test_413a() {
25889         [ $MDSCOUNT -lt 2 ] &&
25890                 skip "We need at least 2 MDTs for this test"
25891
25892         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25893                 skip "Need server version at least 2.12.52"
25894
25895         local stripe_count
25896
25897         generate_uneven_mdts 100
25898         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25899                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25900                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25901                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25902                         error "mkdir failed"
25903                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25904         done
25905 }
25906 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25907
25908 test_413b() {
25909         [ $MDSCOUNT -lt 2 ] &&
25910                 skip "We need at least 2 MDTs for this test"
25911
25912         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25913                 skip "Need server version at least 2.12.52"
25914
25915         local testdir
25916         local stripe_count
25917
25918         generate_uneven_mdts 100
25919         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25920                 testdir=$DIR/$tdir-s$stripe_count
25921                 mkdir $testdir || error "mkdir $testdir failed"
25922                 mkdir $testdir/rr || error "mkdir rr failed"
25923                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25924                         error "mkdir qos failed"
25925                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25926                         $testdir/rr || error "setdirstripe rr failed"
25927                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25928                         error "setdirstripe failed"
25929                 test_qos_mkdir "mkdir" $stripe_count
25930         done
25931 }
25932 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25933
25934 test_413c() {
25935         (( $MDSCOUNT >= 2 )) ||
25936                 skip "We need at least 2 MDTs for this test"
25937
25938         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25939                 skip "Need server version at least 2.14.51"
25940
25941         local testdir
25942         local inherit
25943         local inherit_rr
25944
25945         testdir=$DIR/${tdir}-s1
25946         mkdir $testdir || error "mkdir $testdir failed"
25947         mkdir $testdir/rr || error "mkdir rr failed"
25948         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25949         # default max_inherit is -1, default max_inherit_rr is 0
25950         $LFS setdirstripe -D -c 1 $testdir/rr ||
25951                 error "setdirstripe rr failed"
25952         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25953                 error "setdirstripe qos failed"
25954         test_qos_mkdir "mkdir" 1
25955
25956         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25957         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25958         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25959         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25960         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25961
25962         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25963         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25964         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25965         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25966         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25967         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25968         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25969                 error "level2 shouldn't have default LMV" || true
25970 }
25971 run_test 413c "mkdir with default LMV max inherit rr"
25972
25973 test_413d() {
25974         (( MDSCOUNT >= 2 )) ||
25975                 skip "We need at least 2 MDTs for this test"
25976
25977         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25978                 skip "Need server version at least 2.14.51"
25979
25980         local lmv_qos_threshold_rr
25981
25982         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25983                 head -n1)
25984         stack_trap "$LCTL set_param \
25985                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25986
25987         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25988         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25989         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25990                 error "$tdir shouldn't have default LMV"
25991         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25992                 error "mkdir sub failed"
25993
25994         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25995
25996         (( count == 100 )) || error "$count subdirs on MDT0"
25997 }
25998 run_test 413d "inherit ROOT default LMV"
25999
26000 test_413e() {
26001         (( MDSCOUNT >= 2 )) ||
26002                 skip "We need at least 2 MDTs for this test"
26003         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26004                 skip "Need server version at least 2.14.55"
26005
26006         local testdir=$DIR/$tdir
26007         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26008         local max_inherit
26009         local sub_max_inherit
26010
26011         mkdir -p $testdir || error "failed to create $testdir"
26012
26013         # set default max-inherit to -1 if stripe count is 0 or 1
26014         $LFS setdirstripe -D -c 1 $testdir ||
26015                 error "failed to set default LMV"
26016         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26017         (( max_inherit == -1 )) ||
26018                 error "wrong max_inherit value $max_inherit"
26019
26020         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26021         $LFS setdirstripe -D -c -1 $testdir ||
26022                 error "failed to set default LMV"
26023         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26024         (( max_inherit > 0 )) ||
26025                 error "wrong max_inherit value $max_inherit"
26026
26027         # and the subdir will decrease the max_inherit by 1
26028         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26029         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26030         (( sub_max_inherit == max_inherit - 1)) ||
26031                 error "wrong max-inherit of subdir $sub_max_inherit"
26032
26033         # check specified --max-inherit and warning message
26034         stack_trap "rm -f $tmpfile"
26035         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26036                 error "failed to set default LMV"
26037         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26038         (( max_inherit == -1 )) ||
26039                 error "wrong max_inherit value $max_inherit"
26040
26041         # check the warning messages
26042         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26043                 error "failed to detect warning string"
26044         fi
26045 }
26046 run_test 413e "check default max-inherit value"
26047
26048 test_fs_dmv_inherit()
26049 {
26050         local testdir=$DIR/$tdir
26051
26052         local count
26053         local inherit
26054         local inherit_rr
26055
26056         for i in 1 2 3; do
26057                 mkdir $testdir || error "mkdir $testdir failed"
26058                 count=$($LFS getdirstripe -D -c $testdir)
26059                 (( count == 1 )) ||
26060                         error "$testdir default LMV count mismatch $count != 1"
26061                 inherit=$($LFS getdirstripe -D -X $testdir)
26062                 (( inherit == 3 - i )) ||
26063                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26064                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26065                 (( inherit_rr == 3 - i )) ||
26066                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26067                 testdir=$testdir/sub
26068         done
26069
26070         mkdir $testdir || error "mkdir $testdir failed"
26071         count=$($LFS getdirstripe -D -c $testdir)
26072         (( count == 0 )) ||
26073                 error "$testdir default LMV count not zero: $count"
26074 }
26075
26076 test_413f() {
26077         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26078
26079         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26080                 skip "Need server version at least 2.14.55"
26081
26082         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26083                 error "dump $DIR default LMV failed"
26084         stack_trap "setfattr --restore=$TMP/dmv.ea"
26085
26086         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26087                 error "set $DIR default LMV failed"
26088
26089         test_fs_dmv_inherit
26090 }
26091 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26092
26093 test_413g() {
26094         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26095
26096         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
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         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26105                 error "mount $MOUNT2 failed"
26106         stack_trap "umount_client $MOUNT2"
26107
26108         local saved_DIR=$DIR
26109
26110         export DIR=$MOUNT2
26111
26112         stack_trap "export DIR=$saved_DIR"
26113
26114         # first check filesystem-wide default LMV inheritance
26115         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26116
26117         # then check subdirs are spread to all MDTs
26118         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26119
26120         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26121
26122         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26123 }
26124 run_test 413g "enforce ROOT default LMV on subdir mount"
26125
26126 test_413z() {
26127         local pids=""
26128         local subdir
26129         local pid
26130
26131         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26132                 unlinkmany $subdir/f. 1000 &
26133                 pids="$pids $!"
26134         done
26135
26136         for pid in $pids; do
26137                 wait $pid
26138         done
26139 }
26140 run_test 413z "413 test cleanup"
26141
26142 test_414() {
26143 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26144         $LCTL set_param fail_loc=0x80000521
26145         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26146         rm -f $DIR/$tfile
26147 }
26148 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26149
26150 test_415() {
26151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26152         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26153                 skip "Need server version at least 2.11.52"
26154
26155         # LU-11102
26156         local total
26157         local setattr_pid
26158         local start_time
26159         local end_time
26160         local duration
26161
26162         total=500
26163         # this test may be slow on ZFS
26164         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26165
26166         # though this test is designed for striped directory, let's test normal
26167         # directory too since lock is always saved as CoS lock.
26168         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26169         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26170
26171         (
26172                 while true; do
26173                         touch $DIR/$tdir
26174                 done
26175         ) &
26176         setattr_pid=$!
26177
26178         start_time=$(date +%s)
26179         for i in $(seq $total); do
26180                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26181                         > /dev/null
26182         done
26183         end_time=$(date +%s)
26184         duration=$((end_time - start_time))
26185
26186         kill -9 $setattr_pid
26187
26188         echo "rename $total files took $duration sec"
26189         [ $duration -lt 100 ] || error "rename took $duration sec"
26190 }
26191 run_test 415 "lock revoke is not missing"
26192
26193 test_416() {
26194         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26195                 skip "Need server version at least 2.11.55"
26196
26197         # define OBD_FAIL_OSD_TXN_START    0x19a
26198         do_facet mds1 lctl set_param fail_loc=0x19a
26199
26200         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26201
26202         true
26203 }
26204 run_test 416 "transaction start failure won't cause system hung"
26205
26206 cleanup_417() {
26207         trap 0
26208         do_nodes $(comma_list $(mdts_nodes)) \
26209                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26210         do_nodes $(comma_list $(mdts_nodes)) \
26211                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26212         do_nodes $(comma_list $(mdts_nodes)) \
26213                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26214 }
26215
26216 test_417() {
26217         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26218         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26219                 skip "Need MDS version at least 2.11.56"
26220
26221         trap cleanup_417 RETURN EXIT
26222
26223         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26224         do_nodes $(comma_list $(mdts_nodes)) \
26225                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26226         $LFS migrate -m 0 $DIR/$tdir.1 &&
26227                 error "migrate dir $tdir.1 should fail"
26228
26229         do_nodes $(comma_list $(mdts_nodes)) \
26230                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26231         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26232                 error "create remote dir $tdir.2 should fail"
26233
26234         do_nodes $(comma_list $(mdts_nodes)) \
26235                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26236         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26237                 error "create striped dir $tdir.3 should fail"
26238         true
26239 }
26240 run_test 417 "disable remote dir, striped dir and dir migration"
26241
26242 # Checks that the outputs of df [-i] and lfs df [-i] match
26243 #
26244 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26245 check_lfs_df() {
26246         local dir=$2
26247         local inodes
26248         local df_out
26249         local lfs_df_out
26250         local count
26251         local passed=false
26252
26253         # blocks or inodes
26254         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26255
26256         for count in {1..100}; do
26257                 do_nodes "$CLIENTS" \
26258                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26259                 sync; sleep 0.2
26260
26261                 # read the lines of interest
26262                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26263                         error "df $inodes $dir | tail -n +2 failed"
26264                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26265                         error "lfs df $inodes $dir | grep summary: failed"
26266
26267                 # skip first substrings of each output as they are different
26268                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26269                 # compare the two outputs
26270                 passed=true
26271                 #  skip "available" on MDT until LU-13997 is fixed.
26272                 #for i in {1..5}; do
26273                 for i in 1 2 4 5; do
26274                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26275                 done
26276                 $passed && break
26277         done
26278
26279         if ! $passed; then
26280                 df -P $inodes $dir
26281                 echo
26282                 lfs df $inodes $dir
26283                 error "df and lfs df $1 output mismatch: "      \
26284                       "df ${inodes}: ${df_out[*]}, "            \
26285                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26286         fi
26287 }
26288
26289 test_418() {
26290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26291
26292         local dir=$DIR/$tdir
26293         local numfiles=$((RANDOM % 4096 + 2))
26294         local numblocks=$((RANDOM % 256 + 1))
26295
26296         wait_delete_completed
26297         test_mkdir $dir
26298
26299         # check block output
26300         check_lfs_df blocks $dir
26301         # check inode output
26302         check_lfs_df inodes $dir
26303
26304         # create a single file and retest
26305         echo "Creating a single file and testing"
26306         createmany -o $dir/$tfile- 1 &>/dev/null ||
26307                 error "creating 1 file in $dir failed"
26308         check_lfs_df blocks $dir
26309         check_lfs_df inodes $dir
26310
26311         # create a random number of files
26312         echo "Creating $((numfiles - 1)) files and testing"
26313         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26314                 error "creating $((numfiles - 1)) files in $dir failed"
26315
26316         # write a random number of blocks to the first test file
26317         echo "Writing $numblocks 4K blocks and testing"
26318         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26319                 count=$numblocks &>/dev/null ||
26320                 error "dd to $dir/${tfile}-0 failed"
26321
26322         # retest
26323         check_lfs_df blocks $dir
26324         check_lfs_df inodes $dir
26325
26326         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26327                 error "unlinking $numfiles files in $dir failed"
26328 }
26329 run_test 418 "df and lfs df outputs match"
26330
26331 test_419()
26332 {
26333         local dir=$DIR/$tdir
26334
26335         mkdir -p $dir
26336         touch $dir/file
26337
26338         cancel_lru_locks mdc
26339
26340         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26341         $LCTL set_param fail_loc=0x1410
26342         cat $dir/file
26343         $LCTL set_param fail_loc=0
26344         rm -rf $dir
26345 }
26346 run_test 419 "Verify open file by name doesn't crash kernel"
26347
26348 test_420()
26349 {
26350         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26351                 skip "Need MDS version at least 2.12.53"
26352
26353         local SAVE_UMASK=$(umask)
26354         local dir=$DIR/$tdir
26355         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26356
26357         mkdir -p $dir
26358         umask 0000
26359         mkdir -m03777 $dir/testdir
26360         ls -dn $dir/testdir
26361         # Need to remove trailing '.' when SELinux is enabled
26362         local dirperms=$(ls -dn $dir/testdir |
26363                          awk '{ sub(/\.$/, "", $1); print $1}')
26364         [ $dirperms == "drwxrwsrwt" ] ||
26365                 error "incorrect perms on $dir/testdir"
26366
26367         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26368                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26369         ls -n $dir/testdir/testfile
26370         local fileperms=$(ls -n $dir/testdir/testfile |
26371                           awk '{ sub(/\.$/, "", $1); print $1}')
26372         [ $fileperms == "-rwxr-xr-x" ] ||
26373                 error "incorrect perms on $dir/testdir/testfile"
26374
26375         umask $SAVE_UMASK
26376 }
26377 run_test 420 "clear SGID bit on non-directories for non-members"
26378
26379 test_421a() {
26380         local cnt
26381         local fid1
26382         local fid2
26383
26384         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26385                 skip "Need MDS version at least 2.12.54"
26386
26387         test_mkdir $DIR/$tdir
26388         createmany -o $DIR/$tdir/f 3
26389         cnt=$(ls -1 $DIR/$tdir | wc -l)
26390         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26391
26392         fid1=$(lfs path2fid $DIR/$tdir/f1)
26393         fid2=$(lfs path2fid $DIR/$tdir/f2)
26394         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26395
26396         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26397         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26398
26399         cnt=$(ls -1 $DIR/$tdir | wc -l)
26400         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26401
26402         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26403         createmany -o $DIR/$tdir/f 3
26404         cnt=$(ls -1 $DIR/$tdir | wc -l)
26405         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26406
26407         fid1=$(lfs path2fid $DIR/$tdir/f1)
26408         fid2=$(lfs path2fid $DIR/$tdir/f2)
26409         echo "remove using fsname $FSNAME"
26410         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26411
26412         cnt=$(ls -1 $DIR/$tdir | wc -l)
26413         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26414 }
26415 run_test 421a "simple rm by fid"
26416
26417 test_421b() {
26418         local cnt
26419         local FID1
26420         local FID2
26421
26422         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26423                 skip "Need MDS version at least 2.12.54"
26424
26425         test_mkdir $DIR/$tdir
26426         createmany -o $DIR/$tdir/f 3
26427         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26428         MULTIPID=$!
26429
26430         FID1=$(lfs path2fid $DIR/$tdir/f1)
26431         FID2=$(lfs path2fid $DIR/$tdir/f2)
26432         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26433
26434         kill -USR1 $MULTIPID
26435         wait
26436
26437         cnt=$(ls $DIR/$tdir | wc -l)
26438         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26439 }
26440 run_test 421b "rm by fid on open file"
26441
26442 test_421c() {
26443         local cnt
26444         local FIDS
26445
26446         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26447                 skip "Need MDS version at least 2.12.54"
26448
26449         test_mkdir $DIR/$tdir
26450         createmany -o $DIR/$tdir/f 3
26451         touch $DIR/$tdir/$tfile
26452         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26453         cnt=$(ls -1 $DIR/$tdir | wc -l)
26454         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26455
26456         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26457         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26458
26459         cnt=$(ls $DIR/$tdir | wc -l)
26460         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26461 }
26462 run_test 421c "rm by fid against hardlinked files"
26463
26464 test_421d() {
26465         local cnt
26466         local FIDS
26467
26468         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26469                 skip "Need MDS version at least 2.12.54"
26470
26471         test_mkdir $DIR/$tdir
26472         createmany -o $DIR/$tdir/f 4097
26473         cnt=$(ls -1 $DIR/$tdir | wc -l)
26474         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26475
26476         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26477         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26478
26479         cnt=$(ls $DIR/$tdir | wc -l)
26480         rm -rf $DIR/$tdir
26481         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26482 }
26483 run_test 421d "rmfid en masse"
26484
26485 test_421e() {
26486         local cnt
26487         local FID
26488
26489         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26490         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26491                 skip "Need MDS version at least 2.12.54"
26492
26493         mkdir -p $DIR/$tdir
26494         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26495         createmany -o $DIR/$tdir/striped_dir/f 512
26496         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26497         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26498
26499         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26500                 sed "s/[/][^:]*://g")
26501         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26502
26503         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26504         rm -rf $DIR/$tdir
26505         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26506 }
26507 run_test 421e "rmfid in DNE"
26508
26509 test_421f() {
26510         local cnt
26511         local FID
26512
26513         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26514                 skip "Need MDS version at least 2.12.54"
26515
26516         test_mkdir $DIR/$tdir
26517         touch $DIR/$tdir/f
26518         cnt=$(ls -1 $DIR/$tdir | wc -l)
26519         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26520
26521         FID=$(lfs path2fid $DIR/$tdir/f)
26522         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26523         # rmfid should fail
26524         cnt=$(ls -1 $DIR/$tdir | wc -l)
26525         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26526
26527         chmod a+rw $DIR/$tdir
26528         ls -la $DIR/$tdir
26529         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26530         # rmfid should fail
26531         cnt=$(ls -1 $DIR/$tdir | wc -l)
26532         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26533
26534         rm -f $DIR/$tdir/f
26535         $RUNAS touch $DIR/$tdir/f
26536         FID=$(lfs path2fid $DIR/$tdir/f)
26537         echo "rmfid as root"
26538         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26539         cnt=$(ls -1 $DIR/$tdir | wc -l)
26540         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26541
26542         rm -f $DIR/$tdir/f
26543         $RUNAS touch $DIR/$tdir/f
26544         cnt=$(ls -1 $DIR/$tdir | wc -l)
26545         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26546         FID=$(lfs path2fid $DIR/$tdir/f)
26547         # rmfid w/o user_fid2path mount option should fail
26548         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26549         cnt=$(ls -1 $DIR/$tdir | wc -l)
26550         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26551
26552         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26553         stack_trap "rmdir $tmpdir"
26554         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26555                 error "failed to mount client'"
26556         stack_trap "umount_client $tmpdir"
26557
26558         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26559         # rmfid should succeed
26560         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26561         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26562
26563         # rmfid shouldn't allow to remove files due to dir's permission
26564         chmod a+rwx $tmpdir/$tdir
26565         touch $tmpdir/$tdir/f
26566         ls -la $tmpdir/$tdir
26567         FID=$(lfs path2fid $tmpdir/$tdir/f)
26568         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26569         return 0
26570 }
26571 run_test 421f "rmfid checks permissions"
26572
26573 test_421g() {
26574         local cnt
26575         local FIDS
26576
26577         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26578         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26579                 skip "Need MDS version at least 2.12.54"
26580
26581         mkdir -p $DIR/$tdir
26582         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26583         createmany -o $DIR/$tdir/striped_dir/f 512
26584         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26585         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26586
26587         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26588                 sed "s/[/][^:]*://g")
26589
26590         rm -f $DIR/$tdir/striped_dir/f1*
26591         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26592         removed=$((512 - cnt))
26593
26594         # few files have been just removed, so we expect
26595         # rmfid to fail on their fids
26596         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26597         [ $removed != $errors ] && error "$errors != $removed"
26598
26599         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26600         rm -rf $DIR/$tdir
26601         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26602 }
26603 run_test 421g "rmfid to return errors properly"
26604
26605 test_422() {
26606         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26607         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26608         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26609         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26610         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26611
26612         local amc=$(at_max_get client)
26613         local amo=$(at_max_get mds1)
26614         local timeout=`lctl get_param -n timeout`
26615
26616         at_max_set 0 client
26617         at_max_set 0 mds1
26618
26619 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26620         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26621                         fail_val=$(((2*timeout + 10)*1000))
26622         touch $DIR/$tdir/d3/file &
26623         sleep 2
26624 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26625         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26626                         fail_val=$((2*timeout + 5))
26627         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26628         local pid=$!
26629         sleep 1
26630         kill -9 $pid
26631         sleep $((2 * timeout))
26632         echo kill $pid
26633         kill -9 $pid
26634         lctl mark touch
26635         touch $DIR/$tdir/d2/file3
26636         touch $DIR/$tdir/d2/file4
26637         touch $DIR/$tdir/d2/file5
26638
26639         wait
26640         at_max_set $amc client
26641         at_max_set $amo mds1
26642
26643         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26644         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26645                 error "Watchdog is always throttled"
26646 }
26647 run_test 422 "kill a process with RPC in progress"
26648
26649 stat_test() {
26650     df -h $MOUNT &
26651     df -h $MOUNT &
26652     df -h $MOUNT &
26653     df -h $MOUNT &
26654     df -h $MOUNT &
26655     df -h $MOUNT &
26656 }
26657
26658 test_423() {
26659     local _stats
26660     # ensure statfs cache is expired
26661     sleep 2;
26662
26663     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26664     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26665
26666     return 0
26667 }
26668 run_test 423 "statfs should return a right data"
26669
26670 test_424() {
26671 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26672         $LCTL set_param fail_loc=0x80000522
26673         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26674         rm -f $DIR/$tfile
26675 }
26676 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26677
26678 test_425() {
26679         test_mkdir -c -1 $DIR/$tdir
26680         $LFS setstripe -c -1 $DIR/$tdir
26681
26682         lru_resize_disable "" 100
26683         stack_trap "lru_resize_enable" EXIT
26684
26685         sleep 5
26686
26687         for i in $(seq $((MDSCOUNT * 125))); do
26688                 local t=$DIR/$tdir/$tfile_$i
26689
26690                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26691                         error_noexit "Create file $t"
26692         done
26693         stack_trap "rm -rf $DIR/$tdir" EXIT
26694
26695         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26696                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26697                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26698
26699                 [ $lock_count -le $lru_size ] ||
26700                         error "osc lock count $lock_count > lru size $lru_size"
26701         done
26702
26703         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26704                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26705                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26706
26707                 [ $lock_count -le $lru_size ] ||
26708                         error "mdc lock count $lock_count > lru size $lru_size"
26709         done
26710 }
26711 run_test 425 "lock count should not exceed lru size"
26712
26713 test_426() {
26714         splice-test -r $DIR/$tfile
26715         splice-test -rd $DIR/$tfile
26716         splice-test $DIR/$tfile
26717         splice-test -d $DIR/$tfile
26718 }
26719 run_test 426 "splice test on Lustre"
26720
26721 test_427() {
26722         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26723         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26724                 skip "Need MDS version at least 2.12.4"
26725         local log
26726
26727         mkdir $DIR/$tdir
26728         mkdir $DIR/$tdir/1
26729         mkdir $DIR/$tdir/2
26730         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26731         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26732
26733         $LFS getdirstripe $DIR/$tdir/1/dir
26734
26735         #first setfattr for creating updatelog
26736         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26737
26738 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26739         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26740         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26741         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26742
26743         sleep 2
26744         fail mds2
26745         wait_recovery_complete mds2 $((2*TIMEOUT))
26746
26747         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26748         echo $log | grep "get update log failed" &&
26749                 error "update log corruption is detected" || true
26750 }
26751 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26752
26753 test_428() {
26754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26755         local cache_limit=$CACHE_MAX
26756
26757         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26758         $LCTL set_param -n llite.*.max_cached_mb=64
26759
26760         mkdir $DIR/$tdir
26761         $LFS setstripe -c 1 $DIR/$tdir
26762         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26763         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26764         #test write
26765         for f in $(seq 4); do
26766                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26767         done
26768         wait
26769
26770         cancel_lru_locks osc
26771         # Test read
26772         for f in $(seq 4); do
26773                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26774         done
26775         wait
26776 }
26777 run_test 428 "large block size IO should not hang"
26778
26779 test_429() { # LU-7915 / LU-10948
26780         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26781         local testfile=$DIR/$tfile
26782         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26783         local new_flag=1
26784         local first_rpc
26785         local second_rpc
26786         local third_rpc
26787
26788         $LCTL get_param $ll_opencache_threshold_count ||
26789                 skip "client does not have opencache parameter"
26790
26791         set_opencache $new_flag
26792         stack_trap "restore_opencache"
26793         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26794                 error "enable opencache failed"
26795         touch $testfile
26796         # drop MDC DLM locks
26797         cancel_lru_locks mdc
26798         # clear MDC RPC stats counters
26799         $LCTL set_param $mdc_rpcstats=clear
26800
26801         # According to the current implementation, we need to run 3 times
26802         # open & close file to verify if opencache is enabled correctly.
26803         # 1st, RPCs are sent for lookup/open and open handle is released on
26804         #      close finally.
26805         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26806         #      so open handle won't be released thereafter.
26807         # 3rd, No RPC is sent out.
26808         $MULTIOP $testfile oc || error "multiop failed"
26809         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26810         echo "1st: $first_rpc RPCs in flight"
26811
26812         $MULTIOP $testfile oc || error "multiop failed"
26813         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26814         echo "2nd: $second_rpc RPCs in flight"
26815
26816         $MULTIOP $testfile oc || error "multiop failed"
26817         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26818         echo "3rd: $third_rpc RPCs in flight"
26819
26820         #verify no MDC RPC is sent
26821         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26822 }
26823 run_test 429 "verify if opencache flag on client side does work"
26824
26825 lseek_test_430() {
26826         local offset
26827         local file=$1
26828
26829         # data at [200K, 400K)
26830         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26831                 error "256K->512K dd fails"
26832         # data at [2M, 3M)
26833         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26834                 error "2M->3M dd fails"
26835         # data at [4M, 5M)
26836         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26837                 error "4M->5M dd fails"
26838         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26839         # start at first component hole #1
26840         printf "Seeking hole from 1000 ... "
26841         offset=$(lseek_test -l 1000 $file)
26842         echo $offset
26843         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26844         printf "Seeking data from 1000 ... "
26845         offset=$(lseek_test -d 1000 $file)
26846         echo $offset
26847         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26848
26849         # start at first component data block
26850         printf "Seeking hole from 300000 ... "
26851         offset=$(lseek_test -l 300000 $file)
26852         echo $offset
26853         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26854         printf "Seeking data from 300000 ... "
26855         offset=$(lseek_test -d 300000 $file)
26856         echo $offset
26857         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26858
26859         # start at the first component but beyond end of object size
26860         printf "Seeking hole from 1000000 ... "
26861         offset=$(lseek_test -l 1000000 $file)
26862         echo $offset
26863         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26864         printf "Seeking data from 1000000 ... "
26865         offset=$(lseek_test -d 1000000 $file)
26866         echo $offset
26867         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26868
26869         # start at second component stripe 2 (empty file)
26870         printf "Seeking hole from 1500000 ... "
26871         offset=$(lseek_test -l 1500000 $file)
26872         echo $offset
26873         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26874         printf "Seeking data from 1500000 ... "
26875         offset=$(lseek_test -d 1500000 $file)
26876         echo $offset
26877         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26878
26879         # start at second component stripe 1 (all data)
26880         printf "Seeking hole from 3000000 ... "
26881         offset=$(lseek_test -l 3000000 $file)
26882         echo $offset
26883         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26884         printf "Seeking data from 3000000 ... "
26885         offset=$(lseek_test -d 3000000 $file)
26886         echo $offset
26887         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26888
26889         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26890                 error "2nd dd fails"
26891         echo "Add data block at 640K...1280K"
26892
26893         # start at before new data block, in hole
26894         printf "Seeking hole from 600000 ... "
26895         offset=$(lseek_test -l 600000 $file)
26896         echo $offset
26897         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26898         printf "Seeking data from 600000 ... "
26899         offset=$(lseek_test -d 600000 $file)
26900         echo $offset
26901         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26902
26903         # start at the first component new data block
26904         printf "Seeking hole from 1000000 ... "
26905         offset=$(lseek_test -l 1000000 $file)
26906         echo $offset
26907         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26908         printf "Seeking data from 1000000 ... "
26909         offset=$(lseek_test -d 1000000 $file)
26910         echo $offset
26911         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26912
26913         # start at second component stripe 2, new data
26914         printf "Seeking hole from 1200000 ... "
26915         offset=$(lseek_test -l 1200000 $file)
26916         echo $offset
26917         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26918         printf "Seeking data from 1200000 ... "
26919         offset=$(lseek_test -d 1200000 $file)
26920         echo $offset
26921         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26922
26923         # start beyond file end
26924         printf "Using offset > filesize ... "
26925         lseek_test -l 4000000 $file && error "lseek should fail"
26926         printf "Using offset > filesize ... "
26927         lseek_test -d 4000000 $file && error "lseek should fail"
26928
26929         printf "Done\n\n"
26930 }
26931
26932 test_430a() {
26933         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26934                 skip "MDT does not support SEEK_HOLE"
26935
26936         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26937                 skip "OST does not support SEEK_HOLE"
26938
26939         local file=$DIR/$tdir/$tfile
26940
26941         mkdir -p $DIR/$tdir
26942
26943         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26944         # OST stripe #1 will have continuous data at [1M, 3M)
26945         # OST stripe #2 is empty
26946         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26947         lseek_test_430 $file
26948         rm $file
26949         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26950         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26951         lseek_test_430 $file
26952         rm $file
26953         $LFS setstripe -c2 -S 512K $file
26954         echo "Two stripes, stripe size 512K"
26955         lseek_test_430 $file
26956         rm $file
26957         # FLR with stale mirror
26958         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26959                        -N -c2 -S 1M $file
26960         echo "Mirrored file:"
26961         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26962         echo "Plain 2 stripes 1M"
26963         lseek_test_430 $file
26964         rm $file
26965 }
26966 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26967
26968 test_430b() {
26969         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26970                 skip "OST does not support SEEK_HOLE"
26971
26972         local offset
26973         local file=$DIR/$tdir/$tfile
26974
26975         mkdir -p $DIR/$tdir
26976         # Empty layout lseek should fail
26977         $MCREATE $file
26978         # seek from 0
26979         printf "Seeking hole from 0 ... "
26980         lseek_test -l 0 $file && error "lseek should fail"
26981         printf "Seeking data from 0 ... "
26982         lseek_test -d 0 $file && error "lseek should fail"
26983         rm $file
26984
26985         # 1M-hole file
26986         $LFS setstripe -E 1M -c2 -E eof $file
26987         $TRUNCATE $file 1048576
26988         printf "Seeking hole from 1000000 ... "
26989         offset=$(lseek_test -l 1000000 $file)
26990         echo $offset
26991         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26992         printf "Seeking data from 1000000 ... "
26993         lseek_test -d 1000000 $file && error "lseek should fail"
26994         rm $file
26995
26996         # full component followed by non-inited one
26997         $LFS setstripe -E 1M -c2 -E eof $file
26998         dd if=/dev/urandom of=$file bs=1M count=1
26999         printf "Seeking hole from 1000000 ... "
27000         offset=$(lseek_test -l 1000000 $file)
27001         echo $offset
27002         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27003         printf "Seeking hole from 1048576 ... "
27004         lseek_test -l 1048576 $file && error "lseek should fail"
27005         # init second component and truncate back
27006         echo "123" >> $file
27007         $TRUNCATE $file 1048576
27008         printf "Seeking hole from 1000000 ... "
27009         offset=$(lseek_test -l 1000000 $file)
27010         echo $offset
27011         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27012         printf "Seeking hole from 1048576 ... "
27013         lseek_test -l 1048576 $file && error "lseek should fail"
27014         # boundary checks for big values
27015         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27016         offset=$(lseek_test -d 0 $file.10g)
27017         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27018         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27019         offset=$(lseek_test -d 0 $file.100g)
27020         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27021         return 0
27022 }
27023 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27024
27025 test_430c() {
27026         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27027                 skip "OST does not support SEEK_HOLE"
27028
27029         local file=$DIR/$tdir/$tfile
27030         local start
27031
27032         mkdir -p $DIR/$tdir
27033         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27034
27035         # cp version 8.33+ prefers lseek over fiemap
27036         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27037                 start=$SECONDS
27038                 time cp $file /dev/null
27039                 (( SECONDS - start < 5 )) ||
27040                         error "cp: too long runtime $((SECONDS - start))"
27041
27042         fi
27043         # tar version 1.29+ supports SEEK_HOLE/DATA
27044         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27045                 start=$SECONDS
27046                 time tar cS $file - | cat > /dev/null
27047                 (( SECONDS - start < 5 )) ||
27048                         error "tar: too long runtime $((SECONDS - start))"
27049         fi
27050 }
27051 run_test 430c "lseek: external tools check"
27052
27053 test_431() { # LU-14187
27054         local file=$DIR/$tdir/$tfile
27055
27056         mkdir -p $DIR/$tdir
27057         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27058         dd if=/dev/urandom of=$file bs=4k count=1
27059         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27060         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27061         #define OBD_FAIL_OST_RESTART_IO 0x251
27062         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27063         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27064         cp $file $file.0
27065         cancel_lru_locks
27066         sync_all_data
27067         echo 3 > /proc/sys/vm/drop_caches
27068         diff  $file $file.0 || error "data diff"
27069 }
27070 run_test 431 "Restart transaction for IO"
27071
27072 cleanup_test_432() {
27073         do_facet mgs $LCTL nodemap_activate 0
27074         wait_nm_sync active
27075 }
27076
27077 test_432() {
27078         local tmpdir=$TMP/dir432
27079
27080         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27081                 skip "Need MDS version at least 2.14.52"
27082
27083         stack_trap cleanup_test_432 EXIT
27084         mkdir $DIR/$tdir
27085         mkdir $tmpdir
27086
27087         do_facet mgs $LCTL nodemap_activate 1
27088         wait_nm_sync active
27089         do_facet mgs $LCTL nodemap_modify --name default \
27090                 --property admin --value 1
27091         do_facet mgs $LCTL nodemap_modify --name default \
27092                 --property trusted --value 1
27093         cancel_lru_locks mdc
27094         wait_nm_sync default admin_nodemap
27095         wait_nm_sync default trusted_nodemap
27096
27097         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27098                grep -ci "Operation not permitted") -ne 0 ]; then
27099                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27100         fi
27101 }
27102 run_test 432 "mv dir from outside Lustre"
27103
27104 test_433() {
27105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27106
27107         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27108                 skip "inode cache not supported"
27109
27110         $LCTL set_param llite.*.inode_cache=0
27111         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27112
27113         local count=256
27114         local before
27115         local after
27116
27117         cancel_lru_locks mdc
27118         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27119         createmany -m $DIR/$tdir/f $count
27120         createmany -d $DIR/$tdir/d $count
27121         ls -l $DIR/$tdir > /dev/null
27122         stack_trap "rm -rf $DIR/$tdir"
27123
27124         before=$(num_objects)
27125         cancel_lru_locks mdc
27126         after=$(num_objects)
27127
27128         # sometimes even @before is less than 2 * count
27129         while (( before - after < count )); do
27130                 sleep 1
27131                 after=$(num_objects)
27132                 wait=$((wait + 1))
27133                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27134                 if (( wait > 60 )); then
27135                         error "inode slab grew from $before to $after"
27136                 fi
27137         done
27138
27139         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27140 }
27141 run_test 433 "ldlm lock cancel releases dentries and inodes"
27142
27143 prep_801() {
27144         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27145         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27146                 skip "Need server version at least 2.9.55"
27147
27148         start_full_debug_logging
27149 }
27150
27151 post_801() {
27152         stop_full_debug_logging
27153 }
27154
27155 barrier_stat() {
27156         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27157                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27158                            awk '/The barrier for/ { print $7 }')
27159                 echo $st
27160         else
27161                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27162                 echo \'$st\'
27163         fi
27164 }
27165
27166 barrier_expired() {
27167         local expired
27168
27169         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27170                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27171                           awk '/will be expired/ { print $7 }')
27172         else
27173                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27174         fi
27175
27176         echo $expired
27177 }
27178
27179 test_801a() {
27180         prep_801
27181
27182         echo "Start barrier_freeze at: $(date)"
27183         #define OBD_FAIL_BARRIER_DELAY          0x2202
27184         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27185         # Do not reduce barrier time - See LU-11873
27186         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27187
27188         sleep 2
27189         local b_status=$(barrier_stat)
27190         echo "Got barrier status at: $(date)"
27191         [ "$b_status" = "'freezing_p1'" ] ||
27192                 error "(1) unexpected barrier status $b_status"
27193
27194         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27195         wait
27196         b_status=$(barrier_stat)
27197         [ "$b_status" = "'frozen'" ] ||
27198                 error "(2) unexpected barrier status $b_status"
27199
27200         local expired=$(barrier_expired)
27201         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27202         sleep $((expired + 3))
27203
27204         b_status=$(barrier_stat)
27205         [ "$b_status" = "'expired'" ] ||
27206                 error "(3) unexpected barrier status $b_status"
27207
27208         # Do not reduce barrier time - See LU-11873
27209         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27210                 error "(4) fail to freeze barrier"
27211
27212         b_status=$(barrier_stat)
27213         [ "$b_status" = "'frozen'" ] ||
27214                 error "(5) unexpected barrier status $b_status"
27215
27216         echo "Start barrier_thaw at: $(date)"
27217         #define OBD_FAIL_BARRIER_DELAY          0x2202
27218         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27219         do_facet mgs $LCTL barrier_thaw $FSNAME &
27220
27221         sleep 2
27222         b_status=$(barrier_stat)
27223         echo "Got barrier status at: $(date)"
27224         [ "$b_status" = "'thawing'" ] ||
27225                 error "(6) unexpected barrier status $b_status"
27226
27227         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27228         wait
27229         b_status=$(barrier_stat)
27230         [ "$b_status" = "'thawed'" ] ||
27231                 error "(7) unexpected barrier status $b_status"
27232
27233         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27234         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27235         do_facet mgs $LCTL barrier_freeze $FSNAME
27236
27237         b_status=$(barrier_stat)
27238         [ "$b_status" = "'failed'" ] ||
27239                 error "(8) unexpected barrier status $b_status"
27240
27241         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27242         do_facet mgs $LCTL barrier_thaw $FSNAME
27243
27244         post_801
27245 }
27246 run_test 801a "write barrier user interfaces and stat machine"
27247
27248 test_801b() {
27249         prep_801
27250
27251         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27252         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27253         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27254         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27255         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27256
27257         cancel_lru_locks mdc
27258
27259         # 180 seconds should be long enough
27260         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27261
27262         local b_status=$(barrier_stat)
27263         [ "$b_status" = "'frozen'" ] ||
27264                 error "(6) unexpected barrier status $b_status"
27265
27266         mkdir $DIR/$tdir/d0/d10 &
27267         mkdir_pid=$!
27268
27269         touch $DIR/$tdir/d1/f13 &
27270         touch_pid=$!
27271
27272         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27273         ln_pid=$!
27274
27275         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27276         mv_pid=$!
27277
27278         rm -f $DIR/$tdir/d4/f12 &
27279         rm_pid=$!
27280
27281         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27282
27283         # To guarantee taht the 'stat' is not blocked
27284         b_status=$(barrier_stat)
27285         [ "$b_status" = "'frozen'" ] ||
27286                 error "(8) unexpected barrier status $b_status"
27287
27288         # let above commands to run at background
27289         sleep 5
27290
27291         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27292         ps -p $touch_pid || error "(10) touch should be blocked"
27293         ps -p $ln_pid || error "(11) link should be blocked"
27294         ps -p $mv_pid || error "(12) rename should be blocked"
27295         ps -p $rm_pid || error "(13) unlink should be blocked"
27296
27297         b_status=$(barrier_stat)
27298         [ "$b_status" = "'frozen'" ] ||
27299                 error "(14) unexpected barrier status $b_status"
27300
27301         do_facet mgs $LCTL barrier_thaw $FSNAME
27302         b_status=$(barrier_stat)
27303         [ "$b_status" = "'thawed'" ] ||
27304                 error "(15) unexpected barrier status $b_status"
27305
27306         wait $mkdir_pid || error "(16) mkdir should succeed"
27307         wait $touch_pid || error "(17) touch should succeed"
27308         wait $ln_pid || error "(18) link should succeed"
27309         wait $mv_pid || error "(19) rename should succeed"
27310         wait $rm_pid || error "(20) unlink should succeed"
27311
27312         post_801
27313 }
27314 run_test 801b "modification will be blocked by write barrier"
27315
27316 test_801c() {
27317         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27318
27319         prep_801
27320
27321         stop mds2 || error "(1) Fail to stop mds2"
27322
27323         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27324
27325         local b_status=$(barrier_stat)
27326         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27327                 do_facet mgs $LCTL barrier_thaw $FSNAME
27328                 error "(2) unexpected barrier status $b_status"
27329         }
27330
27331         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27332                 error "(3) Fail to rescan barrier bitmap"
27333
27334         # Do not reduce barrier time - See LU-11873
27335         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27336
27337         b_status=$(barrier_stat)
27338         [ "$b_status" = "'frozen'" ] ||
27339                 error "(4) unexpected barrier status $b_status"
27340
27341         do_facet mgs $LCTL barrier_thaw $FSNAME
27342         b_status=$(barrier_stat)
27343         [ "$b_status" = "'thawed'" ] ||
27344                 error "(5) unexpected barrier status $b_status"
27345
27346         local devname=$(mdsdevname 2)
27347
27348         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27349
27350         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27351                 error "(7) Fail to rescan barrier bitmap"
27352
27353         post_801
27354 }
27355 run_test 801c "rescan barrier bitmap"
27356
27357 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27358 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27359 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27360 saved_MOUNT_OPTS=$MOUNT_OPTS
27361
27362 cleanup_802a() {
27363         trap 0
27364
27365         stopall
27366         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27367         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27368         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27369         MOUNT_OPTS=$saved_MOUNT_OPTS
27370         setupall
27371 }
27372
27373 test_802a() {
27374         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27375         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27376         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27377                 skip "Need server version at least 2.9.55"
27378
27379         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27380
27381         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27382
27383         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27384                 error "(2) Fail to copy"
27385
27386         trap cleanup_802a EXIT
27387
27388         # sync by force before remount as readonly
27389         sync; sync_all_data; sleep 3; sync_all_data
27390
27391         stopall
27392
27393         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27394         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27395         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27396
27397         echo "Mount the server as read only"
27398         setupall server_only || error "(3) Fail to start servers"
27399
27400         echo "Mount client without ro should fail"
27401         mount_client $MOUNT &&
27402                 error "(4) Mount client without 'ro' should fail"
27403
27404         echo "Mount client with ro should succeed"
27405         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27406         mount_client $MOUNT ||
27407                 error "(5) Mount client with 'ro' should succeed"
27408
27409         echo "Modify should be refused"
27410         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27411
27412         echo "Read should be allowed"
27413         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27414                 error "(7) Read should succeed under ro mode"
27415
27416         cleanup_802a
27417 }
27418 run_test 802a "simulate readonly device"
27419
27420 test_802b() {
27421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27422         remote_mds_nodsh && skip "remote MDS with nodsh"
27423
27424         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27425                 skip "readonly option not available"
27426
27427         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27428
27429         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27430                 error "(2) Fail to copy"
27431
27432         # write back all cached data before setting MDT to readonly
27433         cancel_lru_locks
27434         sync_all_data
27435
27436         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27437         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27438
27439         echo "Modify should be refused"
27440         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27441
27442         echo "Read should be allowed"
27443         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27444                 error "(7) Read should succeed under ro mode"
27445
27446         # disable readonly
27447         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27448 }
27449 run_test 802b "be able to set MDTs to readonly"
27450
27451 test_803a() {
27452         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27453         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27454                 skip "MDS needs to be newer than 2.10.54"
27455
27456         mkdir_on_mdt0 $DIR/$tdir
27457         # Create some objects on all MDTs to trigger related logs objects
27458         for idx in $(seq $MDSCOUNT); do
27459                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27460                         $DIR/$tdir/dir${idx} ||
27461                         error "Fail to create $DIR/$tdir/dir${idx}"
27462         done
27463
27464         sync; sleep 3
27465         wait_delete_completed # ensure old test cleanups are finished
27466         echo "before create:"
27467         $LFS df -i $MOUNT
27468         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27469
27470         for i in {1..10}; do
27471                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27472                         error "Fail to create $DIR/$tdir/foo$i"
27473         done
27474
27475         sync; sleep 3
27476         echo "after create:"
27477         $LFS df -i $MOUNT
27478         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27479
27480         # allow for an llog to be cleaned up during the test
27481         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27482                 error "before ($before_used) + 10 > after ($after_used)"
27483
27484         for i in {1..10}; do
27485                 rm -rf $DIR/$tdir/foo$i ||
27486                         error "Fail to remove $DIR/$tdir/foo$i"
27487         done
27488
27489         sleep 3 # avoid MDT return cached statfs
27490         wait_delete_completed
27491         echo "after unlink:"
27492         $LFS df -i $MOUNT
27493         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27494
27495         # allow for an llog to be created during the test
27496         [ $after_used -le $((before_used + 1)) ] ||
27497                 error "after ($after_used) > before ($before_used) + 1"
27498 }
27499 run_test 803a "verify agent object for remote object"
27500
27501 test_803b() {
27502         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27503         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27504                 skip "MDS needs to be newer than 2.13.56"
27505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27506
27507         for i in $(seq 0 $((MDSCOUNT - 1))); do
27508                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27509         done
27510
27511         local before=0
27512         local after=0
27513
27514         local tmp
27515
27516         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27517         for i in $(seq 0 $((MDSCOUNT - 1))); do
27518                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27519                         awk '/getattr/ { print $2 }')
27520                 before=$((before + tmp))
27521         done
27522         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27523         for i in $(seq 0 $((MDSCOUNT - 1))); do
27524                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27525                         awk '/getattr/ { print $2 }')
27526                 after=$((after + tmp))
27527         done
27528
27529         [ $before -eq $after ] || error "getattr count $before != $after"
27530 }
27531 run_test 803b "remote object can getattr from cache"
27532
27533 test_804() {
27534         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27535         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27536                 skip "MDS needs to be newer than 2.10.54"
27537         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27538
27539         mkdir -p $DIR/$tdir
27540         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27541                 error "Fail to create $DIR/$tdir/dir0"
27542
27543         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27544         local dev=$(mdsdevname 2)
27545
27546         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27547                 grep ${fid} || error "NOT found agent entry for dir0"
27548
27549         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27550                 error "Fail to create $DIR/$tdir/dir1"
27551
27552         touch $DIR/$tdir/dir1/foo0 ||
27553                 error "Fail to create $DIR/$tdir/dir1/foo0"
27554         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27555         local rc=0
27556
27557         for idx in $(seq $MDSCOUNT); do
27558                 dev=$(mdsdevname $idx)
27559                 do_facet mds${idx} \
27560                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27561                         grep ${fid} && rc=$idx
27562         done
27563
27564         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27565                 error "Fail to rename foo0 to foo1"
27566         if [ $rc -eq 0 ]; then
27567                 for idx in $(seq $MDSCOUNT); do
27568                         dev=$(mdsdevname $idx)
27569                         do_facet mds${idx} \
27570                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27571                         grep ${fid} && rc=$idx
27572                 done
27573         fi
27574
27575         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27576                 error "Fail to rename foo1 to foo2"
27577         if [ $rc -eq 0 ]; then
27578                 for idx in $(seq $MDSCOUNT); do
27579                         dev=$(mdsdevname $idx)
27580                         do_facet mds${idx} \
27581                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27582                         grep ${fid} && rc=$idx
27583                 done
27584         fi
27585
27586         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27587
27588         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27589                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27590         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27591                 error "Fail to rename foo2 to foo0"
27592         unlink $DIR/$tdir/dir1/foo0 ||
27593                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27594         rm -rf $DIR/$tdir/dir0 ||
27595                 error "Fail to rm $DIR/$tdir/dir0"
27596
27597         for idx in $(seq $MDSCOUNT); do
27598                 rc=0
27599
27600                 stop mds${idx}
27601                 dev=$(mdsdevname $idx)
27602                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27603                         rc=$?
27604                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27605                         error "mount mds$idx failed"
27606                 df $MOUNT > /dev/null 2>&1
27607
27608                 # e2fsck should not return error
27609                 [ $rc -eq 0 ] ||
27610                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27611         done
27612 }
27613 run_test 804 "verify agent entry for remote entry"
27614
27615 cleanup_805() {
27616         do_facet $SINGLEMDS zfs set quota=$old $fsset
27617         unlinkmany $DIR/$tdir/f- 1000000
27618         trap 0
27619 }
27620
27621 test_805() {
27622         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27623         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27624         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27625                 skip "netfree not implemented before 0.7"
27626         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27627                 skip "Need MDS version at least 2.10.57"
27628
27629         local fsset
27630         local freekb
27631         local usedkb
27632         local old
27633         local quota
27634         local pref="osd-zfs.$FSNAME-MDT0000."
27635
27636         # limit available space on MDS dataset to meet nospace issue
27637         # quickly. then ZFS 0.7.2 can use reserved space if asked
27638         # properly (using netfree flag in osd_declare_destroy()
27639         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27640         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27641                 gawk '{print $3}')
27642         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27643         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27644         let "usedkb=usedkb-freekb"
27645         let "freekb=freekb/2"
27646         if let "freekb > 5000"; then
27647                 let "freekb=5000"
27648         fi
27649         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27650         trap cleanup_805 EXIT
27651         mkdir_on_mdt0 $DIR/$tdir
27652         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27653                 error "Can't set PFL layout"
27654         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27655         rm -rf $DIR/$tdir || error "not able to remove"
27656         do_facet $SINGLEMDS zfs set quota=$old $fsset
27657         trap 0
27658 }
27659 run_test 805 "ZFS can remove from full fs"
27660
27661 # Size-on-MDS test
27662 check_lsom_data()
27663 {
27664         local file=$1
27665         local expect=$(stat -c %s $file)
27666
27667         check_lsom_size $1 $expect
27668
27669         local blocks=$($LFS getsom -b $file)
27670         expect=$(stat -c %b $file)
27671         [[ $blocks == $expect ]] ||
27672                 error "$file expected blocks: $expect, got: $blocks"
27673 }
27674
27675 check_lsom_size()
27676 {
27677         local size
27678         local expect=$2
27679
27680         cancel_lru_locks mdc
27681
27682         size=$($LFS getsom -s $1)
27683         [[ $size == $expect ]] ||
27684                 error "$file expected size: $expect, got: $size"
27685 }
27686
27687 test_806() {
27688         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27689                 skip "Need MDS version at least 2.11.52"
27690
27691         local bs=1048576
27692
27693         touch $DIR/$tfile || error "touch $tfile failed"
27694
27695         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27696         save_lustre_params client "llite.*.xattr_cache" > $save
27697         lctl set_param llite.*.xattr_cache=0
27698         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27699
27700         # single-threaded write
27701         echo "Test SOM for single-threaded write"
27702         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27703                 error "write $tfile failed"
27704         check_lsom_size $DIR/$tfile $bs
27705
27706         local num=32
27707         local size=$(($num * $bs))
27708         local offset=0
27709         local i
27710
27711         echo "Test SOM for single client multi-threaded($num) write"
27712         $TRUNCATE $DIR/$tfile 0
27713         for ((i = 0; i < $num; i++)); do
27714                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27715                 local pids[$i]=$!
27716                 offset=$((offset + $bs))
27717         done
27718         for (( i=0; i < $num; i++ )); do
27719                 wait ${pids[$i]}
27720         done
27721         check_lsom_size $DIR/$tfile $size
27722
27723         $TRUNCATE $DIR/$tfile 0
27724         for ((i = 0; i < $num; i++)); do
27725                 offset=$((offset - $bs))
27726                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27727                 local pids[$i]=$!
27728         done
27729         for (( i=0; i < $num; i++ )); do
27730                 wait ${pids[$i]}
27731         done
27732         check_lsom_size $DIR/$tfile $size
27733
27734         # multi-client writes
27735         num=$(get_node_count ${CLIENTS//,/ })
27736         size=$(($num * $bs))
27737         offset=0
27738         i=0
27739
27740         echo "Test SOM for multi-client ($num) writes"
27741         $TRUNCATE $DIR/$tfile 0
27742         for client in ${CLIENTS//,/ }; do
27743                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27744                 local pids[$i]=$!
27745                 i=$((i + 1))
27746                 offset=$((offset + $bs))
27747         done
27748         for (( i=0; i < $num; i++ )); do
27749                 wait ${pids[$i]}
27750         done
27751         check_lsom_size $DIR/$tfile $offset
27752
27753         i=0
27754         $TRUNCATE $DIR/$tfile 0
27755         for client in ${CLIENTS//,/ }; do
27756                 offset=$((offset - $bs))
27757                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27758                 local pids[$i]=$!
27759                 i=$((i + 1))
27760         done
27761         for (( i=0; i < $num; i++ )); do
27762                 wait ${pids[$i]}
27763         done
27764         check_lsom_size $DIR/$tfile $size
27765
27766         # verify truncate
27767         echo "Test SOM for truncate"
27768         $TRUNCATE $DIR/$tfile 1048576
27769         check_lsom_size $DIR/$tfile 1048576
27770         $TRUNCATE $DIR/$tfile 1234
27771         check_lsom_size $DIR/$tfile 1234
27772
27773         # verify SOM blocks count
27774         echo "Verify SOM block count"
27775         $TRUNCATE $DIR/$tfile 0
27776         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27777                 error "failed to write file $tfile"
27778         check_lsom_data $DIR/$tfile
27779 }
27780 run_test 806 "Verify Lazy Size on MDS"
27781
27782 test_807() {
27783         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27784         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27785                 skip "Need MDS version at least 2.11.52"
27786
27787         # Registration step
27788         changelog_register || error "changelog_register failed"
27789         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27790         changelog_users $SINGLEMDS | grep -q $cl_user ||
27791                 error "User $cl_user not found in changelog_users"
27792
27793         rm -rf $DIR/$tdir || error "rm $tdir failed"
27794         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27795         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27796         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27797         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27798                 error "truncate $tdir/trunc failed"
27799
27800         local bs=1048576
27801         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27802                 error "write $tfile failed"
27803
27804         # multi-client wirtes
27805         local num=$(get_node_count ${CLIENTS//,/ })
27806         local offset=0
27807         local i=0
27808
27809         echo "Test SOM for multi-client ($num) writes"
27810         touch $DIR/$tfile || error "touch $tfile failed"
27811         $TRUNCATE $DIR/$tfile 0
27812         for client in ${CLIENTS//,/ }; do
27813                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27814                 local pids[$i]=$!
27815                 i=$((i + 1))
27816                 offset=$((offset + $bs))
27817         done
27818         for (( i=0; i < $num; i++ )); do
27819                 wait ${pids[$i]}
27820         done
27821
27822         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27823         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27824         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27825         check_lsom_data $DIR/$tdir/trunc
27826         check_lsom_data $DIR/$tdir/single_dd
27827         check_lsom_data $DIR/$tfile
27828
27829         rm -rf $DIR/$tdir
27830         # Deregistration step
27831         changelog_deregister || error "changelog_deregister failed"
27832 }
27833 run_test 807 "verify LSOM syncing tool"
27834
27835 check_som_nologged()
27836 {
27837         local lines=$($LFS changelog $FSNAME-MDT0000 |
27838                 grep 'x=trusted.som' | wc -l)
27839         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27840 }
27841
27842 test_808() {
27843         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27844                 skip "Need MDS version at least 2.11.55"
27845
27846         # Registration step
27847         changelog_register || error "changelog_register failed"
27848
27849         touch $DIR/$tfile || error "touch $tfile failed"
27850         check_som_nologged
27851
27852         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27853                 error "write $tfile failed"
27854         check_som_nologged
27855
27856         $TRUNCATE $DIR/$tfile 1234
27857         check_som_nologged
27858
27859         $TRUNCATE $DIR/$tfile 1048576
27860         check_som_nologged
27861
27862         # Deregistration step
27863         changelog_deregister || error "changelog_deregister failed"
27864 }
27865 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27866
27867 check_som_nodata()
27868 {
27869         $LFS getsom $1
27870         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27871 }
27872
27873 test_809() {
27874         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27875                 skip "Need MDS version at least 2.11.56"
27876
27877         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27878                 error "failed to create DoM-only file $DIR/$tfile"
27879         touch $DIR/$tfile || error "touch $tfile failed"
27880         check_som_nodata $DIR/$tfile
27881
27882         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27883                 error "write $tfile failed"
27884         check_som_nodata $DIR/$tfile
27885
27886         $TRUNCATE $DIR/$tfile 1234
27887         check_som_nodata $DIR/$tfile
27888
27889         $TRUNCATE $DIR/$tfile 4097
27890         check_som_nodata $DIR/$file
27891 }
27892 run_test 809 "Verify no SOM xattr store for DoM-only files"
27893
27894 test_810() {
27895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27896         $GSS && skip_env "could not run with gss"
27897         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27898                 skip "OST < 2.12.58 doesn't align checksum"
27899
27900         set_checksums 1
27901         stack_trap "set_checksums $ORIG_CSUM" EXIT
27902         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27903
27904         local csum
27905         local before
27906         local after
27907         for csum in $CKSUM_TYPES; do
27908                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27909                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27910                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27911                         eval set -- $i
27912                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27913                         before=$(md5sum $DIR/$tfile)
27914                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27915                         after=$(md5sum $DIR/$tfile)
27916                         [ "$before" == "$after" ] ||
27917                                 error "$csum: $before != $after bs=$1 seek=$2"
27918                 done
27919         done
27920 }
27921 run_test 810 "partial page writes on ZFS (LU-11663)"
27922
27923 test_812a() {
27924         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27925                 skip "OST < 2.12.51 doesn't support this fail_loc"
27926
27927         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27928         # ensure ost1 is connected
27929         stat $DIR/$tfile >/dev/null || error "can't stat"
27930         wait_osc_import_state client ost1 FULL
27931         # no locks, no reqs to let the connection idle
27932         cancel_lru_locks osc
27933
27934         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27935 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27936         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27937         wait_osc_import_state client ost1 CONNECTING
27938         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27939
27940         stat $DIR/$tfile >/dev/null || error "can't stat file"
27941 }
27942 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27943
27944 test_812b() { # LU-12378
27945         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27946                 skip "OST < 2.12.51 doesn't support this fail_loc"
27947
27948         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27949         # ensure ost1 is connected
27950         stat $DIR/$tfile >/dev/null || error "can't stat"
27951         wait_osc_import_state client ost1 FULL
27952         # no locks, no reqs to let the connection idle
27953         cancel_lru_locks osc
27954
27955         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27956 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27957         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27958         wait_osc_import_state client ost1 CONNECTING
27959         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27960
27961         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27962         wait_osc_import_state client ost1 IDLE
27963 }
27964 run_test 812b "do not drop no resend request for idle connect"
27965
27966 test_812c() {
27967         local old
27968
27969         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27970
27971         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27972         $LFS getstripe $DIR/$tfile
27973         $LCTL set_param osc.*.idle_timeout=10
27974         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27975         # ensure ost1 is connected
27976         stat $DIR/$tfile >/dev/null || error "can't stat"
27977         wait_osc_import_state client ost1 FULL
27978         # no locks, no reqs to let the connection idle
27979         cancel_lru_locks osc
27980
27981 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27982         $LCTL set_param fail_loc=0x80000533
27983         sleep 15
27984         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27985 }
27986 run_test 812c "idle import vs lock enqueue race"
27987
27988 test_813() {
27989         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27990         [ -z "$file_heat_sav" ] && skip "no file heat support"
27991
27992         local readsample
27993         local writesample
27994         local readbyte
27995         local writebyte
27996         local readsample1
27997         local writesample1
27998         local readbyte1
27999         local writebyte1
28000
28001         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28002         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28003
28004         $LCTL set_param -n llite.*.file_heat=1
28005         echo "Turn on file heat"
28006         echo "Period second: $period_second, Decay percentage: $decay_pct"
28007
28008         echo "QQQQ" > $DIR/$tfile
28009         echo "QQQQ" > $DIR/$tfile
28010         echo "QQQQ" > $DIR/$tfile
28011         cat $DIR/$tfile > /dev/null
28012         cat $DIR/$tfile > /dev/null
28013         cat $DIR/$tfile > /dev/null
28014         cat $DIR/$tfile > /dev/null
28015
28016         local out=$($LFS heat_get $DIR/$tfile)
28017
28018         $LFS heat_get $DIR/$tfile
28019         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28020         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28021         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28022         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28023
28024         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28025         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28026         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28027         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28028
28029         sleep $((period_second + 3))
28030         echo "Sleep $((period_second + 3)) seconds..."
28031         # The recursion formula to calculate the heat of the file f is as
28032         # follow:
28033         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28034         # Where Hi is the heat value in the period between time points i*I and
28035         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28036         # to the weight of Ci.
28037         out=$($LFS heat_get $DIR/$tfile)
28038         $LFS heat_get $DIR/$tfile
28039         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28040         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28041         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28042         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28043
28044         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28045                 error "read sample ($readsample) is wrong"
28046         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28047                 error "write sample ($writesample) is wrong"
28048         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28049                 error "read bytes ($readbyte) is wrong"
28050         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28051                 error "write bytes ($writebyte) is wrong"
28052
28053         echo "QQQQ" > $DIR/$tfile
28054         echo "QQQQ" > $DIR/$tfile
28055         echo "QQQQ" > $DIR/$tfile
28056         cat $DIR/$tfile > /dev/null
28057         cat $DIR/$tfile > /dev/null
28058         cat $DIR/$tfile > /dev/null
28059         cat $DIR/$tfile > /dev/null
28060
28061         sleep $((period_second + 3))
28062         echo "Sleep $((period_second + 3)) seconds..."
28063
28064         out=$($LFS heat_get $DIR/$tfile)
28065         $LFS heat_get $DIR/$tfile
28066         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28067         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28068         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28069         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28070
28071         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28072                 4 * $decay_pct) / 100") -eq 1 ] ||
28073                 error "read sample ($readsample1) is wrong"
28074         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28075                 3 * $decay_pct) / 100") -eq 1 ] ||
28076                 error "write sample ($writesample1) is wrong"
28077         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28078                 20 * $decay_pct) / 100") -eq 1 ] ||
28079                 error "read bytes ($readbyte1) is wrong"
28080         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28081                 15 * $decay_pct) / 100") -eq 1 ] ||
28082                 error "write bytes ($writebyte1) is wrong"
28083
28084         echo "Turn off file heat for the file $DIR/$tfile"
28085         $LFS heat_set -o $DIR/$tfile
28086
28087         echo "QQQQ" > $DIR/$tfile
28088         echo "QQQQ" > $DIR/$tfile
28089         echo "QQQQ" > $DIR/$tfile
28090         cat $DIR/$tfile > /dev/null
28091         cat $DIR/$tfile > /dev/null
28092         cat $DIR/$tfile > /dev/null
28093         cat $DIR/$tfile > /dev/null
28094
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         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28103         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28104         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28105         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28106
28107         echo "Trun on file heat for the file $DIR/$tfile"
28108         $LFS heat_set -O $DIR/$tfile
28109
28110         echo "QQQQ" > $DIR/$tfile
28111         echo "QQQQ" > $DIR/$tfile
28112         echo "QQQQ" > $DIR/$tfile
28113         cat $DIR/$tfile > /dev/null
28114         cat $DIR/$tfile > /dev/null
28115         cat $DIR/$tfile > /dev/null
28116         cat $DIR/$tfile > /dev/null
28117
28118         out=$($LFS heat_get $DIR/$tfile)
28119         $LFS heat_get $DIR/$tfile
28120         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28121         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28122         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28123         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28124
28125         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28126         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28127         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28128         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28129
28130         $LFS heat_set -c $DIR/$tfile
28131         $LCTL set_param -n llite.*.file_heat=0
28132         echo "Turn off file heat support for the Lustre filesystem"
28133
28134         echo "QQQQ" > $DIR/$tfile
28135         echo "QQQQ" > $DIR/$tfile
28136         echo "QQQQ" > $DIR/$tfile
28137         cat $DIR/$tfile > /dev/null
28138         cat $DIR/$tfile > /dev/null
28139         cat $DIR/$tfile > /dev/null
28140         cat $DIR/$tfile > /dev/null
28141
28142         out=$($LFS heat_get $DIR/$tfile)
28143         $LFS heat_get $DIR/$tfile
28144         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28145         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28146         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28147         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28148
28149         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28150         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28151         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28152         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28153
28154         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28155         rm -f $DIR/$tfile
28156 }
28157 run_test 813 "File heat verfication"
28158
28159 test_814()
28160 {
28161         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28162         echo -n y >> $DIR/$tfile
28163         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28164         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28165 }
28166 run_test 814 "sparse cp works as expected (LU-12361)"
28167
28168 test_815()
28169 {
28170         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28171         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28172 }
28173 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28174
28175 test_816() {
28176         local ost1_imp=$(get_osc_import_name client ost1)
28177         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28178                          cut -d'.' -f2)
28179
28180         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28181         # ensure ost1 is connected
28182
28183         stat $DIR/$tfile >/dev/null || error "can't stat"
28184         wait_osc_import_state client ost1 FULL
28185         # no locks, no reqs to let the connection idle
28186         cancel_lru_locks osc
28187         lru_resize_disable osc
28188         local before
28189         local now
28190         before=$($LCTL get_param -n \
28191                  ldlm.namespaces.$imp_name.lru_size)
28192
28193         wait_osc_import_state client ost1 IDLE
28194         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28195         now=$($LCTL get_param -n \
28196               ldlm.namespaces.$imp_name.lru_size)
28197         [ $before == $now ] || error "lru_size changed $before != $now"
28198 }
28199 run_test 816 "do not reset lru_resize on idle reconnect"
28200
28201 cleanup_817() {
28202         umount $tmpdir
28203         exportfs -u localhost:$DIR/nfsexp
28204         rm -rf $DIR/nfsexp
28205 }
28206
28207 test_817() {
28208         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28209
28210         mkdir -p $DIR/nfsexp
28211         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28212                 error "failed to export nfs"
28213
28214         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28215         stack_trap cleanup_817 EXIT
28216
28217         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28218                 error "failed to mount nfs to $tmpdir"
28219
28220         cp /bin/true $tmpdir
28221         $DIR/nfsexp/true || error "failed to execute 'true' command"
28222 }
28223 run_test 817 "nfsd won't cache write lock for exec file"
28224
28225 test_818() {
28226         test_mkdir -i0 -c1 $DIR/$tdir
28227         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28228         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28229         stop $SINGLEMDS
28230
28231         # restore osp-syn threads
28232         stack_trap "fail $SINGLEMDS"
28233
28234         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28235         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28236         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28237                 error "start $SINGLEMDS failed"
28238         rm -rf $DIR/$tdir
28239
28240         local testid=$(echo $TESTNAME | tr '_' ' ')
28241
28242         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28243                 grep "run LFSCK" || error "run LFSCK is not suggested"
28244 }
28245 run_test 818 "unlink with failed llog"
28246
28247 test_819a() {
28248         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28249         cancel_lru_locks osc
28250         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28251         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28252         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28253         rm -f $TDIR/$tfile
28254 }
28255 run_test 819a "too big niobuf in read"
28256
28257 test_819b() {
28258         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28259         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28260         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28261         cancel_lru_locks osc
28262         sleep 1
28263         rm -f $TDIR/$tfile
28264 }
28265 run_test 819b "too big niobuf in write"
28266
28267
28268 function test_820_start_ost() {
28269         sleep 5
28270
28271         for num in $(seq $OSTCOUNT); do
28272                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28273         done
28274 }
28275
28276 test_820() {
28277         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28278
28279         mkdir $DIR/$tdir
28280         umount_client $MOUNT || error "umount failed"
28281         for num in $(seq $OSTCOUNT); do
28282                 stop ost$num
28283         done
28284
28285         # mount client with no active OSTs
28286         # so that the client can't initialize max LOV EA size
28287         # from OSC notifications
28288         mount_client $MOUNT || error "mount failed"
28289         # delay OST starting to keep this 0 max EA size for a while
28290         test_820_start_ost &
28291
28292         # create a directory on MDS2
28293         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28294                 error "Failed to create directory"
28295         # open intent should update default EA size
28296         # see mdc_update_max_ea_from_body()
28297         # notice this is the very first RPC to MDS2
28298         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28299         ret=$?
28300         echo $out
28301         # With SSK, this situation can lead to -EPERM being returned.
28302         # In that case, simply retry.
28303         if [ $ret -ne 0 ] && $SHARED_KEY; then
28304                 if echo "$out" | grep -q "not permitted"; then
28305                         cp /etc/services $DIR/$tdir/mds2
28306                         ret=$?
28307                 fi
28308         fi
28309         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28310 }
28311 run_test 820 "update max EA from open intent"
28312
28313 test_822() {
28314         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28315
28316         save_lustre_params mds1 \
28317                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28318         do_facet $SINGLEMDS "$LCTL set_param -n \
28319                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28320         do_facet $SINGLEMDS "$LCTL set_param -n \
28321                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28322
28323         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28324         local maxage=$(do_facet mds1 $LCTL get_param -n \
28325                        osp.$FSNAME-OST0000*MDT0000.maxage)
28326         sleep $((maxage + 1))
28327
28328         #define OBD_FAIL_NET_ERROR_RPC          0x532
28329         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28330
28331         stack_trap "restore_lustre_params < $p; rm $p"
28332
28333         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28334                       osp.$FSNAME-OST0000*MDT0000.create_count")
28335         for i in $(seq 1 $count); do
28336                 touch $DIR/$tfile.${i} || error "touch failed"
28337         done
28338 }
28339 run_test 822 "test precreate failure"
28340
28341 test_823() {
28342         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28343         local OST_MAX_PRECREATE=20000
28344
28345         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28346                 skip "Need MDS version at least 2.14.56"
28347
28348         save_lustre_params mds1 \
28349                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28350         do_facet $SINGLEMDS "$LCTL set_param -n \
28351                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28352         do_facet $SINGLEMDS "$LCTL set_param -n \
28353                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28354
28355         stack_trap "restore_lustre_params < $p; rm $p"
28356
28357         do_facet $SINGLEMDS "$LCTL set_param -n \
28358                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28359
28360         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28361                       osp.$FSNAME-OST0000*MDT0000.create_count")
28362         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28363                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28364         local expect_count=$(((($max/2)/256) * 256))
28365
28366         log "setting create_count to 100200:"
28367         log " -result- count: $count with max: $max, expecting: $expect_count"
28368
28369         [[ $count -eq expect_count ]] ||
28370                 error "Create count not set to max precreate."
28371 }
28372 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28373
28374 test_831() {
28375         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28376                 skip "Need MDS version 2.14.56"
28377
28378         local sync_changes=$(do_facet $SINGLEMDS \
28379                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28380
28381         [ "$sync_changes" -gt 100 ] &&
28382                 skip "Sync changes $sync_changes > 100 already"
28383
28384         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28385
28386         $LFS mkdir -i 0 $DIR/$tdir
28387         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28388
28389         save_lustre_params mds1 \
28390                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28391         save_lustre_params mds1 \
28392                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28393
28394         do_facet mds1 "$LCTL set_param -n \
28395                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28396                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28397         stack_trap "restore_lustre_params < $p" EXIT
28398
28399         createmany -o $DIR/$tdir/f- 1000
28400         unlinkmany $DIR/$tdir/f- 1000 &
28401         local UNLINK_PID=$!
28402
28403         while sleep 1; do
28404                 sync_changes=$(do_facet mds1 \
28405                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28406                 # the check in the code is racy, fail the test
28407                 # if the value above the limit by 10.
28408                 [ $sync_changes -gt 110 ] && {
28409                         kill -2 $UNLINK_PID
28410                         wait
28411                         error "osp changes throttling failed, $sync_changes>110"
28412                 }
28413                 kill -0 $UNLINK_PID 2> /dev/null || break
28414         done
28415         wait
28416 }
28417 run_test 831 "throttling unlink/setattr queuing on OSP"
28418
28419 #
28420 # tests that do cleanup/setup should be run at the end
28421 #
28422
28423 test_900() {
28424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28425         local ls
28426
28427         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28428         $LCTL set_param fail_loc=0x903
28429
28430         cancel_lru_locks MGC
28431
28432         FAIL_ON_ERROR=true cleanup
28433         FAIL_ON_ERROR=true setup
28434 }
28435 run_test 900 "umount should not race with any mgc requeue thread"
28436
28437 # LUS-6253/LU-11185
28438 test_901() {
28439         local old
28440         local count
28441         local oldc
28442         local newc
28443         local olds
28444         local news
28445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28446
28447         # some get_param have a bug to handle dot in param name
28448         cancel_lru_locks MGC
28449         old=$(mount -t lustre | wc -l)
28450         # 1 config+sptlrpc
28451         # 2 params
28452         # 3 nodemap
28453         # 4 IR
28454         old=$((old * 4))
28455         oldc=0
28456         count=0
28457         while [ $old -ne $oldc ]; do
28458                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28459                 sleep 1
28460                 ((count++))
28461                 if [ $count -ge $TIMEOUT ]; then
28462                         error "too large timeout"
28463                 fi
28464         done
28465         umount_client $MOUNT || error "umount failed"
28466         mount_client $MOUNT || error "mount failed"
28467         cancel_lru_locks MGC
28468         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28469
28470         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28471
28472         return 0
28473 }
28474 run_test 901 "don't leak a mgc lock on client umount"
28475
28476 # LU-13377
28477 test_902() {
28478         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28479                 skip "client does not have LU-13377 fix"
28480         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28481         $LCTL set_param fail_loc=0x1415
28482         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28483         cancel_lru_locks osc
28484         rm -f $DIR/$tfile
28485 }
28486 run_test 902 "test short write doesn't hang lustre"
28487
28488 # LU-14711
28489 test_903() {
28490         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28491         echo "blah" > $DIR/${tfile}-2
28492         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28493         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28494         $LCTL set_param fail_loc=0x417 fail_val=20
28495
28496         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28497         sleep 1 # To start the destroy
28498         wait_destroy_complete 150 || error "Destroy taking too long"
28499         cat $DIR/$tfile > /dev/null || error "Evicted"
28500 }
28501 run_test 903 "Test long page discard does not cause evictions"
28502
28503 test_904() {
28504         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28505         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28506                 grep -q project || skip "skip project quota not supported"
28507
28508         local testfile="$DIR/$tdir/$tfile"
28509         local xattr="trusted.projid"
28510         local projid
28511         local mdts=$(comma_list $(mdts_nodes))
28512         local saved=$(do_facet mds1 $LCTL get_param -n \
28513                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28514
28515         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28516         stack_trap "do_nodes $mdts $LCTL set_param \
28517                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28518
28519         mkdir -p $DIR/$tdir
28520         touch $testfile
28521         #hide projid xattr on server
28522         $LFS project -p 1 $testfile ||
28523                 error "set $testfile project id failed"
28524         getfattr -m - $testfile | grep $xattr &&
28525                 error "do not show trusted.projid when disabled on server"
28526         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28527         #should be hidden when projid is 0
28528         $LFS project -p 0 $testfile ||
28529                 error "set $testfile project id failed"
28530         getfattr -m - $testfile | grep $xattr &&
28531                 error "do not show trusted.projid with project ID 0"
28532
28533         #still can getxattr explicitly
28534         projid=$(getfattr -n $xattr $testfile |
28535                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28536         [ $projid == "0" ] ||
28537                 error "projid expected 0 not $projid"
28538
28539         #set the projid via setxattr
28540         setfattr -n $xattr -v "1000" $testfile ||
28541                 error "setattr failed with $?"
28542         projid=($($LFS project $testfile))
28543         [ ${projid[0]} == "1000" ] ||
28544                 error "projid expected 1000 not $projid"
28545
28546         #check the new projid via getxattr
28547         $LFS project -p 1001 $testfile ||
28548                 error "set $testfile project id failed"
28549         getfattr -m - $testfile | grep $xattr ||
28550                 error "should show trusted.projid when project ID != 0"
28551         projid=$(getfattr -n $xattr $testfile |
28552                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28553         [ $projid == "1001" ] ||
28554                 error "projid expected 1001 not $projid"
28555
28556         #try to set invalid projid
28557         setfattr -n $xattr -v "4294967295" $testfile &&
28558                 error "set invalid projid should fail"
28559
28560         #remove the xattr means setting projid to 0
28561         setfattr -x $xattr $testfile ||
28562                 error "setfattr failed with $?"
28563         projid=($($LFS project $testfile))
28564         [ ${projid[0]} == "0" ] ||
28565                 error "projid expected 0 not $projid"
28566
28567         #should be hidden when parent has inherit flag and same projid
28568         $LFS project -srp 1002 $DIR/$tdir ||
28569                 error "set $tdir project id failed"
28570         getfattr -m - $testfile | grep $xattr &&
28571                 error "do not show trusted.projid with inherit flag"
28572
28573         #still can getxattr explicitly
28574         projid=$(getfattr -n $xattr $testfile |
28575                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28576         [ $projid == "1002" ] ||
28577                 error "projid expected 1002 not $projid"
28578 }
28579 run_test 904 "virtual project ID xattr"
28580
28581 complete $SECONDS
28582 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28583 check_and_cleanup_lustre
28584 if [ "$I_MOUNTED" != "yes" ]; then
28585         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28586 fi
28587 exit_status