Whamcloud - gitweb
LU-15727 lod: honor append_pool with default composite layouts
[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 # it would be good to share it with obdfilter-survey/iokit-libecho code
17861 setup_obdecho_osc () {
17862         local rc=0
17863         local ost_nid=$1
17864         local obdfilter_name=$2
17865         echo "Creating new osc for $obdfilter_name on $ost_nid"
17866         # make sure we can find loopback nid
17867         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17868
17869         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17870                            ${obdfilter_name}_osc_UUID || rc=2; }
17871         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17872                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17873         return $rc
17874 }
17875
17876 cleanup_obdecho_osc () {
17877         local obdfilter_name=$1
17878         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17879         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17880         return 0
17881 }
17882
17883 obdecho_test() {
17884         local OBD=$1
17885         local node=$2
17886         local pages=${3:-64}
17887         local rc=0
17888         local id
17889
17890         local count=10
17891         local obd_size=$(get_obd_size $node $OBD)
17892         local page_size=$(get_page_size $node)
17893         if [[ -n "$obd_size" ]]; then
17894                 local new_count=$((obd_size / (pages * page_size / 1024)))
17895                 [[ $new_count -ge $count ]] || count=$new_count
17896         fi
17897
17898         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17899         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17900                            rc=2; }
17901         if [ $rc -eq 0 ]; then
17902             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17903             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17904         fi
17905         echo "New object id is $id"
17906         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17907                            rc=4; }
17908         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17909                            "test_brw $count w v $pages $id" || rc=4; }
17910         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17911                            rc=4; }
17912         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17913                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17914         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17915                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17916         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17917         return $rc
17918 }
17919
17920 test_180a() {
17921         skip "obdecho on osc is no longer supported"
17922 }
17923 run_test 180a "test obdecho on osc"
17924
17925 test_180b() {
17926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17927         remote_ost_nodsh && skip "remote OST with nodsh"
17928
17929         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17930                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17931                 error "failed to load module obdecho"
17932
17933         local target=$(do_facet ost1 $LCTL dl |
17934                        awk '/obdfilter/ { print $4; exit; }')
17935
17936         if [ -n "$target" ]; then
17937                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17938         else
17939                 do_facet ost1 $LCTL dl
17940                 error "there is no obdfilter target on ost1"
17941         fi
17942 }
17943 run_test 180b "test obdecho directly on obdfilter"
17944
17945 test_180c() { # LU-2598
17946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17947         remote_ost_nodsh && skip "remote OST with nodsh"
17948         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17949                 skip "Need MDS version at least 2.4.0"
17950
17951         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17952                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17953                 error "failed to load module obdecho"
17954
17955         local target=$(do_facet ost1 $LCTL dl |
17956                        awk '/obdfilter/ { print $4; exit; }')
17957
17958         if [ -n "$target" ]; then
17959                 local pages=16384 # 64MB bulk I/O RPC size
17960
17961                 obdecho_test "$target" ost1 "$pages" ||
17962                         error "obdecho_test with pages=$pages failed with $?"
17963         else
17964                 do_facet ost1 $LCTL dl
17965                 error "there is no obdfilter target on ost1"
17966         fi
17967 }
17968 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17969
17970 test_181() { # bug 22177
17971         test_mkdir $DIR/$tdir
17972         # create enough files to index the directory
17973         createmany -o $DIR/$tdir/foobar 4000
17974         # print attributes for debug purpose
17975         lsattr -d .
17976         # open dir
17977         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17978         MULTIPID=$!
17979         # remove the files & current working dir
17980         unlinkmany $DIR/$tdir/foobar 4000
17981         rmdir $DIR/$tdir
17982         kill -USR1 $MULTIPID
17983         wait $MULTIPID
17984         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17985         return 0
17986 }
17987 run_test 181 "Test open-unlinked dir ========================"
17988
17989 test_182a() {
17990         local fcount=1000
17991         local tcount=10
17992
17993         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17994
17995         $LCTL set_param mdc.*.rpc_stats=clear
17996
17997         for (( i = 0; i < $tcount; i++ )) ; do
17998                 mkdir $DIR/$tdir/$i
17999         done
18000
18001         for (( i = 0; i < $tcount; i++ )) ; do
18002                 createmany -o $DIR/$tdir/$i/f- $fcount &
18003         done
18004         wait
18005
18006         for (( i = 0; i < $tcount; i++ )) ; do
18007                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18008         done
18009         wait
18010
18011         $LCTL get_param mdc.*.rpc_stats
18012
18013         rm -rf $DIR/$tdir
18014 }
18015 run_test 182a "Test parallel modify metadata operations from mdc"
18016
18017 test_182b() {
18018         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18019         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18020         local dcount=1000
18021         local tcount=10
18022         local stime
18023         local etime
18024         local delta
18025
18026         do_facet mds1 $LCTL list_param \
18027                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18028                 skip "MDS lacks parallel RPC handling"
18029
18030         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18031
18032         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18033                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18034
18035         stime=$(date +%s)
18036         createmany -i 0 -d $DIR/$tdir/t- $tcount
18037
18038         for (( i = 0; i < $tcount; i++ )) ; do
18039                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18040         done
18041         wait
18042         etime=$(date +%s)
18043         delta=$((etime - stime))
18044         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18045
18046         stime=$(date +%s)
18047         for (( i = 0; i < $tcount; i++ )) ; do
18048                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18049         done
18050         wait
18051         etime=$(date +%s)
18052         delta=$((etime - stime))
18053         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18054
18055         rm -rf $DIR/$tdir
18056
18057         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18058
18059         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18060
18061         stime=$(date +%s)
18062         createmany -i 0 -d $DIR/$tdir/t- $tcount
18063
18064         for (( i = 0; i < $tcount; i++ )) ; do
18065                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18066         done
18067         wait
18068         etime=$(date +%s)
18069         delta=$((etime - stime))
18070         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18071
18072         stime=$(date +%s)
18073         for (( i = 0; i < $tcount; i++ )) ; do
18074                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18075         done
18076         wait
18077         etime=$(date +%s)
18078         delta=$((etime - stime))
18079         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18080
18081         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18082 }
18083 run_test 182b "Test parallel modify metadata operations from osp"
18084
18085 test_183() { # LU-2275
18086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18087         remote_mds_nodsh && skip "remote MDS with nodsh"
18088         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18089                 skip "Need MDS version at least 2.3.56"
18090
18091         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18092         echo aaa > $DIR/$tdir/$tfile
18093
18094 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18095         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18096
18097         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18098         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18099
18100         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18101
18102         # Flush negative dentry cache
18103         touch $DIR/$tdir/$tfile
18104
18105         # We are not checking for any leaked references here, they'll
18106         # become evident next time we do cleanup with module unload.
18107         rm -rf $DIR/$tdir
18108 }
18109 run_test 183 "No crash or request leak in case of strange dispositions ========"
18110
18111 # test suite 184 is for LU-2016, LU-2017
18112 test_184a() {
18113         check_swap_layouts_support
18114
18115         dir0=$DIR/$tdir/$testnum
18116         test_mkdir -p -c1 $dir0
18117         ref1=/etc/passwd
18118         ref2=/etc/group
18119         file1=$dir0/f1
18120         file2=$dir0/f2
18121         $LFS setstripe -c1 $file1
18122         cp $ref1 $file1
18123         $LFS setstripe -c2 $file2
18124         cp $ref2 $file2
18125         gen1=$($LFS getstripe -g $file1)
18126         gen2=$($LFS getstripe -g $file2)
18127
18128         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18129         gen=$($LFS getstripe -g $file1)
18130         [[ $gen1 != $gen ]] ||
18131                 error "Layout generation on $file1 does not change"
18132         gen=$($LFS getstripe -g $file2)
18133         [[ $gen2 != $gen ]] ||
18134                 error "Layout generation on $file2 does not change"
18135
18136         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18137         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18138
18139         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18140 }
18141 run_test 184a "Basic layout swap"
18142
18143 test_184b() {
18144         check_swap_layouts_support
18145
18146         dir0=$DIR/$tdir/$testnum
18147         mkdir -p $dir0 || error "creating dir $dir0"
18148         file1=$dir0/f1
18149         file2=$dir0/f2
18150         file3=$dir0/f3
18151         dir1=$dir0/d1
18152         dir2=$dir0/d2
18153         mkdir $dir1 $dir2
18154         $LFS setstripe -c1 $file1
18155         $LFS setstripe -c2 $file2
18156         $LFS setstripe -c1 $file3
18157         chown $RUNAS_ID $file3
18158         gen1=$($LFS getstripe -g $file1)
18159         gen2=$($LFS getstripe -g $file2)
18160
18161         $LFS swap_layouts $dir1 $dir2 &&
18162                 error "swap of directories layouts should fail"
18163         $LFS swap_layouts $dir1 $file1 &&
18164                 error "swap of directory and file layouts should fail"
18165         $RUNAS $LFS swap_layouts $file1 $file2 &&
18166                 error "swap of file we cannot write should fail"
18167         $LFS swap_layouts $file1 $file3 &&
18168                 error "swap of file with different owner should fail"
18169         /bin/true # to clear error code
18170 }
18171 run_test 184b "Forbidden layout swap (will generate errors)"
18172
18173 test_184c() {
18174         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18175         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18176         check_swap_layouts_support
18177         check_swap_layout_no_dom $DIR
18178
18179         local dir0=$DIR/$tdir/$testnum
18180         mkdir -p $dir0 || error "creating dir $dir0"
18181
18182         local ref1=$dir0/ref1
18183         local ref2=$dir0/ref2
18184         local file1=$dir0/file1
18185         local file2=$dir0/file2
18186         # create a file large enough for the concurrent test
18187         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18188         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18189         echo "ref file size: ref1($(stat -c %s $ref1))," \
18190              "ref2($(stat -c %s $ref2))"
18191
18192         cp $ref2 $file2
18193         dd if=$ref1 of=$file1 bs=16k &
18194         local DD_PID=$!
18195
18196         # Make sure dd starts to copy file, but wait at most 5 seconds
18197         local loops=0
18198         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18199
18200         $LFS swap_layouts $file1 $file2
18201         local rc=$?
18202         wait $DD_PID
18203         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18204         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18205
18206         # how many bytes copied before swapping layout
18207         local copied=$(stat -c %s $file2)
18208         local remaining=$(stat -c %s $ref1)
18209         remaining=$((remaining - copied))
18210         echo "Copied $copied bytes before swapping layout..."
18211
18212         cmp -n $copied $file1 $ref2 | grep differ &&
18213                 error "Content mismatch [0, $copied) of ref2 and file1"
18214         cmp -n $copied $file2 $ref1 ||
18215                 error "Content mismatch [0, $copied) of ref1 and file2"
18216         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18217                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18218
18219         # clean up
18220         rm -f $ref1 $ref2 $file1 $file2
18221 }
18222 run_test 184c "Concurrent write and layout swap"
18223
18224 test_184d() {
18225         check_swap_layouts_support
18226         check_swap_layout_no_dom $DIR
18227         [ -z "$(which getfattr 2>/dev/null)" ] &&
18228                 skip_env "no getfattr command"
18229
18230         local file1=$DIR/$tdir/$tfile-1
18231         local file2=$DIR/$tdir/$tfile-2
18232         local file3=$DIR/$tdir/$tfile-3
18233         local lovea1
18234         local lovea2
18235
18236         mkdir -p $DIR/$tdir
18237         touch $file1 || error "create $file1 failed"
18238         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18239                 error "create $file2 failed"
18240         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18241                 error "create $file3 failed"
18242         lovea1=$(get_layout_param $file1)
18243
18244         $LFS swap_layouts $file2 $file3 ||
18245                 error "swap $file2 $file3 layouts failed"
18246         $LFS swap_layouts $file1 $file2 ||
18247                 error "swap $file1 $file2 layouts failed"
18248
18249         lovea2=$(get_layout_param $file2)
18250         echo "$lovea1"
18251         echo "$lovea2"
18252         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18253
18254         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18255         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18256 }
18257 run_test 184d "allow stripeless layouts swap"
18258
18259 test_184e() {
18260         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18261                 skip "Need MDS version at least 2.6.94"
18262         check_swap_layouts_support
18263         check_swap_layout_no_dom $DIR
18264         [ -z "$(which getfattr 2>/dev/null)" ] &&
18265                 skip_env "no getfattr command"
18266
18267         local file1=$DIR/$tdir/$tfile-1
18268         local file2=$DIR/$tdir/$tfile-2
18269         local file3=$DIR/$tdir/$tfile-3
18270         local lovea
18271
18272         mkdir -p $DIR/$tdir
18273         touch $file1 || error "create $file1 failed"
18274         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18275                 error "create $file2 failed"
18276         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18277                 error "create $file3 failed"
18278
18279         $LFS swap_layouts $file1 $file2 ||
18280                 error "swap $file1 $file2 layouts failed"
18281
18282         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18283         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18284
18285         echo 123 > $file1 || error "Should be able to write into $file1"
18286
18287         $LFS swap_layouts $file1 $file3 ||
18288                 error "swap $file1 $file3 layouts failed"
18289
18290         echo 123 > $file1 || error "Should be able to write into $file1"
18291
18292         rm -rf $file1 $file2 $file3
18293 }
18294 run_test 184e "Recreate layout after stripeless layout swaps"
18295
18296 test_184f() {
18297         # Create a file with name longer than sizeof(struct stat) ==
18298         # 144 to see if we can get chars from the file name to appear
18299         # in the returned striping. Note that 'f' == 0x66.
18300         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18301
18302         mkdir -p $DIR/$tdir
18303         mcreate $DIR/$tdir/$file
18304         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18305                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18306         fi
18307 }
18308 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18309
18310 test_185() { # LU-2441
18311         # LU-3553 - no volatile file support in old servers
18312         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18313                 skip "Need MDS version at least 2.3.60"
18314
18315         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18316         touch $DIR/$tdir/spoo
18317         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18318         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18319                 error "cannot create/write a volatile file"
18320         [ "$FILESET" == "" ] &&
18321         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18322                 error "FID is still valid after close"
18323
18324         multiop_bg_pause $DIR/$tdir vVw4096_c
18325         local multi_pid=$!
18326
18327         local OLD_IFS=$IFS
18328         IFS=":"
18329         local fidv=($fid)
18330         IFS=$OLD_IFS
18331         # assume that the next FID for this client is sequential, since stdout
18332         # is unfortunately eaten by multiop_bg_pause
18333         local n=$((${fidv[1]} + 1))
18334         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18335         if [ "$FILESET" == "" ]; then
18336                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18337                         error "FID is missing before close"
18338         fi
18339         kill -USR1 $multi_pid
18340         # 1 second delay, so if mtime change we will see it
18341         sleep 1
18342         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18343         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18344 }
18345 run_test 185 "Volatile file support"
18346
18347 function create_check_volatile() {
18348         local idx=$1
18349         local tgt
18350
18351         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18352         local PID=$!
18353         sleep 1
18354         local FID=$(cat /tmp/${tfile}.fid)
18355         [ "$FID" == "" ] && error "can't get FID for volatile"
18356         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18357         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18358         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18359         kill -USR1 $PID
18360         wait
18361         sleep 1
18362         cancel_lru_locks mdc # flush opencache
18363         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18364         return 0
18365 }
18366
18367 test_185a(){
18368         # LU-12516 - volatile creation via .lustre
18369         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18370                 skip "Need MDS version at least 2.3.55"
18371
18372         create_check_volatile 0
18373         [ $MDSCOUNT -lt 2 ] && return 0
18374
18375         # DNE case
18376         create_check_volatile 1
18377
18378         return 0
18379 }
18380 run_test 185a "Volatile file creation in .lustre/fid/"
18381
18382 test_187a() {
18383         remote_mds_nodsh && skip "remote MDS with nodsh"
18384         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18385                 skip "Need MDS version at least 2.3.0"
18386
18387         local dir0=$DIR/$tdir/$testnum
18388         mkdir -p $dir0 || error "creating dir $dir0"
18389
18390         local file=$dir0/file1
18391         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18392         local dv1=$($LFS data_version $file)
18393         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18394         local dv2=$($LFS data_version $file)
18395         [[ $dv1 != $dv2 ]] ||
18396                 error "data version did not change on write $dv1 == $dv2"
18397
18398         # clean up
18399         rm -f $file1
18400 }
18401 run_test 187a "Test data version change"
18402
18403 test_187b() {
18404         remote_mds_nodsh && skip "remote MDS with nodsh"
18405         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18406                 skip "Need MDS version at least 2.3.0"
18407
18408         local dir0=$DIR/$tdir/$testnum
18409         mkdir -p $dir0 || error "creating dir $dir0"
18410
18411         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18412         [[ ${DV[0]} != ${DV[1]} ]] ||
18413                 error "data version did not change on write"\
18414                       " ${DV[0]} == ${DV[1]}"
18415
18416         # clean up
18417         rm -f $file1
18418 }
18419 run_test 187b "Test data version change on volatile file"
18420
18421 test_200() {
18422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18423         remote_mgs_nodsh && skip "remote MGS with nodsh"
18424         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18425
18426         local POOL=${POOL:-cea1}
18427         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18428         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18429         # Pool OST targets
18430         local first_ost=0
18431         local last_ost=$(($OSTCOUNT - 1))
18432         local ost_step=2
18433         local ost_list=$(seq $first_ost $ost_step $last_ost)
18434         local ost_range="$first_ost $last_ost $ost_step"
18435         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18436         local file_dir=$POOL_ROOT/file_tst
18437         local subdir=$test_path/subdir
18438         local rc=0
18439
18440         while : ; do
18441                 # former test_200a test_200b
18442                 pool_add $POOL                          || { rc=$? ; break; }
18443                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18444                 # former test_200c test_200d
18445                 mkdir -p $test_path
18446                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18447                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18448                 mkdir -p $subdir
18449                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18450                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18451                                                         || { rc=$? ; break; }
18452                 # former test_200e test_200f
18453                 local files=$((OSTCOUNT*3))
18454                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18455                                                         || { rc=$? ; break; }
18456                 pool_create_files $POOL $file_dir $files "$ost_list" \
18457                                                         || { rc=$? ; break; }
18458                 # former test_200g test_200h
18459                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18460                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18461
18462                 # former test_201a test_201b test_201c
18463                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18464
18465                 local f=$test_path/$tfile
18466                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18467                 pool_remove $POOL $f                    || { rc=$? ; break; }
18468                 break
18469         done
18470
18471         destroy_test_pools
18472
18473         return $rc
18474 }
18475 run_test 200 "OST pools"
18476
18477 # usage: default_attr <count | size | offset>
18478 default_attr() {
18479         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18480 }
18481
18482 # usage: check_default_stripe_attr
18483 check_default_stripe_attr() {
18484         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18485         case $1 in
18486         --stripe-count|-c)
18487                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18488         --stripe-size|-S)
18489                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18490         --stripe-index|-i)
18491                 EXPECTED=-1;;
18492         *)
18493                 error "unknown getstripe attr '$1'"
18494         esac
18495
18496         [ $ACTUAL == $EXPECTED ] ||
18497                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18498 }
18499
18500 test_204a() {
18501         test_mkdir $DIR/$tdir
18502         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18503
18504         check_default_stripe_attr --stripe-count
18505         check_default_stripe_attr --stripe-size
18506         check_default_stripe_attr --stripe-index
18507 }
18508 run_test 204a "Print default stripe attributes"
18509
18510 test_204b() {
18511         test_mkdir $DIR/$tdir
18512         $LFS setstripe --stripe-count 1 $DIR/$tdir
18513
18514         check_default_stripe_attr --stripe-size
18515         check_default_stripe_attr --stripe-index
18516 }
18517 run_test 204b "Print default stripe size and offset"
18518
18519 test_204c() {
18520         test_mkdir $DIR/$tdir
18521         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18522
18523         check_default_stripe_attr --stripe-count
18524         check_default_stripe_attr --stripe-index
18525 }
18526 run_test 204c "Print default stripe count and offset"
18527
18528 test_204d() {
18529         test_mkdir $DIR/$tdir
18530         $LFS setstripe --stripe-index 0 $DIR/$tdir
18531
18532         check_default_stripe_attr --stripe-count
18533         check_default_stripe_attr --stripe-size
18534 }
18535 run_test 204d "Print default stripe count and size"
18536
18537 test_204e() {
18538         test_mkdir $DIR/$tdir
18539         $LFS setstripe -d $DIR/$tdir
18540
18541         check_default_stripe_attr --stripe-count --raw
18542         check_default_stripe_attr --stripe-size --raw
18543         check_default_stripe_attr --stripe-index --raw
18544 }
18545 run_test 204e "Print raw stripe attributes"
18546
18547 test_204f() {
18548         test_mkdir $DIR/$tdir
18549         $LFS setstripe --stripe-count 1 $DIR/$tdir
18550
18551         check_default_stripe_attr --stripe-size --raw
18552         check_default_stripe_attr --stripe-index --raw
18553 }
18554 run_test 204f "Print raw stripe size and offset"
18555
18556 test_204g() {
18557         test_mkdir $DIR/$tdir
18558         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18559
18560         check_default_stripe_attr --stripe-count --raw
18561         check_default_stripe_attr --stripe-index --raw
18562 }
18563 run_test 204g "Print raw stripe count and offset"
18564
18565 test_204h() {
18566         test_mkdir $DIR/$tdir
18567         $LFS setstripe --stripe-index 0 $DIR/$tdir
18568
18569         check_default_stripe_attr --stripe-count --raw
18570         check_default_stripe_attr --stripe-size --raw
18571 }
18572 run_test 204h "Print raw stripe count and size"
18573
18574 # Figure out which job scheduler is being used, if any,
18575 # or use a fake one
18576 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18577         JOBENV=SLURM_JOB_ID
18578 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18579         JOBENV=LSB_JOBID
18580 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18581         JOBENV=PBS_JOBID
18582 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18583         JOBENV=LOADL_STEP_ID
18584 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18585         JOBENV=JOB_ID
18586 else
18587         $LCTL list_param jobid_name > /dev/null 2>&1
18588         if [ $? -eq 0 ]; then
18589                 JOBENV=nodelocal
18590         else
18591                 JOBENV=FAKE_JOBID
18592         fi
18593 fi
18594 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18595
18596 verify_jobstats() {
18597         local cmd=($1)
18598         shift
18599         local facets="$@"
18600
18601 # we don't really need to clear the stats for this test to work, since each
18602 # command has a unique jobid, but it makes debugging easier if needed.
18603 #       for facet in $facets; do
18604 #               local dev=$(convert_facet2label $facet)
18605 #               # clear old jobstats
18606 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18607 #       done
18608
18609         # use a new JobID for each test, or we might see an old one
18610         [ "$JOBENV" = "FAKE_JOBID" ] &&
18611                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18612
18613         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18614
18615         [ "$JOBENV" = "nodelocal" ] && {
18616                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18617                 $LCTL set_param jobid_name=$FAKE_JOBID
18618                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18619         }
18620
18621         log "Test: ${cmd[*]}"
18622         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18623
18624         if [ $JOBENV = "FAKE_JOBID" ]; then
18625                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18626         else
18627                 ${cmd[*]}
18628         fi
18629
18630         # all files are created on OST0000
18631         for facet in $facets; do
18632                 local stats="*.$(convert_facet2label $facet).job_stats"
18633
18634                 # strip out libtool wrappers for in-tree executables
18635                 if (( $(do_facet $facet lctl get_param $stats |
18636                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18637                         do_facet $facet lctl get_param $stats
18638                         error "No jobstats for $JOBVAL found on $facet::$stats"
18639                 fi
18640         done
18641 }
18642
18643 jobstats_set() {
18644         local new_jobenv=$1
18645
18646         set_persistent_param_and_check client "jobid_var" \
18647                 "$FSNAME.sys.jobid_var" $new_jobenv
18648 }
18649
18650 test_205a() { # Job stats
18651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18652         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18653                 skip "Need MDS version with at least 2.7.1"
18654         remote_mgs_nodsh && skip "remote MGS with nodsh"
18655         remote_mds_nodsh && skip "remote MDS with nodsh"
18656         remote_ost_nodsh && skip "remote OST with nodsh"
18657         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18658                 skip "Server doesn't support jobstats"
18659         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18660
18661         local old_jobenv=$($LCTL get_param -n jobid_var)
18662         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18663
18664         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18665                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18666         else
18667                 stack_trap "do_facet mgs $PERM_CMD \
18668                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18669         fi
18670         changelog_register
18671
18672         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18673                                 mdt.*.job_cleanup_interval | head -n 1)
18674         local new_interval=5
18675         do_facet $SINGLEMDS \
18676                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18677         stack_trap "do_facet $SINGLEMDS \
18678                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18679         local start=$SECONDS
18680
18681         local cmd
18682         # mkdir
18683         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18684         verify_jobstats "$cmd" "$SINGLEMDS"
18685         # rmdir
18686         cmd="rmdir $DIR/$tdir"
18687         verify_jobstats "$cmd" "$SINGLEMDS"
18688         # mkdir on secondary MDT
18689         if [ $MDSCOUNT -gt 1 ]; then
18690                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18691                 verify_jobstats "$cmd" "mds2"
18692         fi
18693         # mknod
18694         cmd="mknod $DIR/$tfile c 1 3"
18695         verify_jobstats "$cmd" "$SINGLEMDS"
18696         # unlink
18697         cmd="rm -f $DIR/$tfile"
18698         verify_jobstats "$cmd" "$SINGLEMDS"
18699         # create all files on OST0000 so verify_jobstats can find OST stats
18700         # open & close
18701         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18702         verify_jobstats "$cmd" "$SINGLEMDS"
18703         # setattr
18704         cmd="touch $DIR/$tfile"
18705         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18706         # write
18707         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18708         verify_jobstats "$cmd" "ost1"
18709         # read
18710         cancel_lru_locks osc
18711         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18712         verify_jobstats "$cmd" "ost1"
18713         # truncate
18714         cmd="$TRUNCATE $DIR/$tfile 0"
18715         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18716         # rename
18717         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18718         verify_jobstats "$cmd" "$SINGLEMDS"
18719         # jobstats expiry - sleep until old stats should be expired
18720         local left=$((new_interval + 5 - (SECONDS - start)))
18721         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18722                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18723                         "0" $left
18724         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18725         verify_jobstats "$cmd" "$SINGLEMDS"
18726         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18727             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18728
18729         # Ensure that jobid are present in changelog (if supported by MDS)
18730         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18731                 changelog_dump | tail -10
18732                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18733                 [ $jobids -eq 9 ] ||
18734                         error "Wrong changelog jobid count $jobids != 9"
18735
18736                 # LU-5862
18737                 JOBENV="disable"
18738                 jobstats_set $JOBENV
18739                 touch $DIR/$tfile
18740                 changelog_dump | grep $tfile
18741                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18742                 [ $jobids -eq 0 ] ||
18743                         error "Unexpected jobids when jobid_var=$JOBENV"
18744         fi
18745
18746         # test '%j' access to environment variable - if supported
18747         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18748                 JOBENV="JOBCOMPLEX"
18749                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18750
18751                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18752         fi
18753
18754         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18755                 JOBENV="JOBCOMPLEX"
18756                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18757
18758                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18759         fi
18760
18761         # test '%j' access to per-session jobid - if supported
18762         if lctl list_param jobid_this_session > /dev/null 2>&1
18763         then
18764                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18765                 lctl set_param jobid_this_session=$USER
18766
18767                 JOBENV="JOBCOMPLEX"
18768                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18769
18770                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18771         fi
18772 }
18773 run_test 205a "Verify job stats"
18774
18775 # LU-13117, LU-13597
18776 test_205b() {
18777         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18778                 skip "Need MDS version at least 2.13.54.91"
18779
18780         job_stats="mdt.*.job_stats"
18781         $LCTL set_param $job_stats=clear
18782         # Setting jobid_var to USER might not be supported
18783         $LCTL set_param jobid_var=USER || true
18784         $LCTL set_param jobid_name="%e.%u"
18785         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18786         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18787                 grep "job_id:.*foolish" &&
18788                         error "Unexpected jobid found"
18789         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18790                 grep "open:.*min.*max.*sum" ||
18791                         error "wrong job_stats format found"
18792 }
18793 run_test 205b "Verify job stats jobid and output format"
18794
18795 # LU-13733
18796 test_205c() {
18797         $LCTL set_param llite.*.stats=0
18798         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18799         $LCTL get_param llite.*.stats
18800         $LCTL get_param llite.*.stats | grep \
18801                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18802                         error "wrong client stats format found"
18803 }
18804 run_test 205c "Verify client stats format"
18805
18806 # LU-1480, LU-1773 and LU-1657
18807 test_206() {
18808         mkdir -p $DIR/$tdir
18809         $LFS setstripe -c -1 $DIR/$tdir
18810 #define OBD_FAIL_LOV_INIT 0x1403
18811         $LCTL set_param fail_loc=0xa0001403
18812         $LCTL set_param fail_val=1
18813         touch $DIR/$tdir/$tfile || true
18814 }
18815 run_test 206 "fail lov_init_raid0() doesn't lbug"
18816
18817 test_207a() {
18818         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18819         local fsz=`stat -c %s $DIR/$tfile`
18820         cancel_lru_locks mdc
18821
18822         # do not return layout in getattr intent
18823 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18824         $LCTL set_param fail_loc=0x170
18825         local sz=`stat -c %s $DIR/$tfile`
18826
18827         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18828
18829         rm -rf $DIR/$tfile
18830 }
18831 run_test 207a "can refresh layout at glimpse"
18832
18833 test_207b() {
18834         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18835         local cksum=`md5sum $DIR/$tfile`
18836         local fsz=`stat -c %s $DIR/$tfile`
18837         cancel_lru_locks mdc
18838         cancel_lru_locks osc
18839
18840         # do not return layout in getattr intent
18841 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18842         $LCTL set_param fail_loc=0x171
18843
18844         # it will refresh layout after the file is opened but before read issues
18845         echo checksum is "$cksum"
18846         echo "$cksum" |md5sum -c --quiet || error "file differs"
18847
18848         rm -rf $DIR/$tfile
18849 }
18850 run_test 207b "can refresh layout at open"
18851
18852 test_208() {
18853         # FIXME: in this test suite, only RD lease is used. This is okay
18854         # for now as only exclusive open is supported. After generic lease
18855         # is done, this test suite should be revised. - Jinshan
18856
18857         remote_mds_nodsh && skip "remote MDS with nodsh"
18858         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18859                 skip "Need MDS version at least 2.4.52"
18860
18861         echo "==== test 1: verify get lease work"
18862         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18863
18864         echo "==== test 2: verify lease can be broken by upcoming open"
18865         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18866         local PID=$!
18867         sleep 2
18868
18869         $MULTIOP $DIR/$tfile oO_RDWR:c
18870         kill -USR1 $PID && wait $PID || error "break lease error"
18871
18872         echo "==== test 3: verify lease can't be granted if an open already exists"
18873         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18874         local PID=$!
18875         sleep 2
18876
18877         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18878         kill -USR1 $PID && wait $PID || error "open file error"
18879
18880         echo "==== test 4: lease can sustain over recovery"
18881         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18882         PID=$!
18883         sleep 2
18884
18885         fail mds1
18886
18887         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18888
18889         echo "==== test 5: lease broken can't be regained by replay"
18890         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18891         PID=$!
18892         sleep 2
18893
18894         # open file to break lease and then recovery
18895         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18896         fail mds1
18897
18898         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18899
18900         rm -f $DIR/$tfile
18901 }
18902 run_test 208 "Exclusive open"
18903
18904 test_209() {
18905         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18906                 skip_env "must have disp_stripe"
18907
18908         touch $DIR/$tfile
18909         sync; sleep 5; sync;
18910
18911         echo 3 > /proc/sys/vm/drop_caches
18912         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18913                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18914         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18915
18916         # open/close 500 times
18917         for i in $(seq 500); do
18918                 cat $DIR/$tfile
18919         done
18920
18921         echo 3 > /proc/sys/vm/drop_caches
18922         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18923                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18924         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18925
18926         echo "before: $req_before, after: $req_after"
18927         [ $((req_after - req_before)) -ge 300 ] &&
18928                 error "open/close requests are not freed"
18929         return 0
18930 }
18931 run_test 209 "read-only open/close requests should be freed promptly"
18932
18933 test_210() {
18934         local pid
18935
18936         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18937         pid=$!
18938         sleep 1
18939
18940         $LFS getstripe $DIR/$tfile
18941         kill -USR1 $pid
18942         wait $pid || error "multiop failed"
18943
18944         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18945         pid=$!
18946         sleep 1
18947
18948         $LFS getstripe $DIR/$tfile
18949         kill -USR1 $pid
18950         wait $pid || error "multiop failed"
18951 }
18952 run_test 210 "lfs getstripe does not break leases"
18953
18954 test_212() {
18955         size=`date +%s`
18956         size=$((size % 8192 + 1))
18957         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18958         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18959         rm -f $DIR/f212 $DIR/f212.xyz
18960 }
18961 run_test 212 "Sendfile test ============================================"
18962
18963 test_213() {
18964         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18965         cancel_lru_locks osc
18966         lctl set_param fail_loc=0x8000040f
18967         # generate a read lock
18968         cat $DIR/$tfile > /dev/null
18969         # write to the file, it will try to cancel the above read lock.
18970         cat /etc/hosts >> $DIR/$tfile
18971 }
18972 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18973
18974 test_214() { # for bug 20133
18975         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18976         for (( i=0; i < 340; i++ )) ; do
18977                 touch $DIR/$tdir/d214c/a$i
18978         done
18979
18980         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18981         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18982         ls $DIR/d214c || error "ls $DIR/d214c failed"
18983         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18984         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18985 }
18986 run_test 214 "hash-indexed directory test - bug 20133"
18987
18988 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18989 create_lnet_proc_files() {
18990         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18991 }
18992
18993 # counterpart of create_lnet_proc_files
18994 remove_lnet_proc_files() {
18995         rm -f $TMP/lnet_$1.sys
18996 }
18997
18998 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18999 # 3rd arg as regexp for body
19000 check_lnet_proc_stats() {
19001         local l=$(cat "$TMP/lnet_$1" |wc -l)
19002         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19003
19004         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19005 }
19006
19007 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19008 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19009 # optional and can be regexp for 2nd line (lnet.routes case)
19010 check_lnet_proc_entry() {
19011         local blp=2          # blp stands for 'position of 1st line of body'
19012         [ -z "$5" ] || blp=3 # lnet.routes case
19013
19014         local l=$(cat "$TMP/lnet_$1" |wc -l)
19015         # subtracting one from $blp because the body can be empty
19016         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19017
19018         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19019                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19020
19021         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19022                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19023
19024         # bail out if any unexpected line happened
19025         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19026         [ "$?" != 0 ] || error "$2 misformatted"
19027 }
19028
19029 test_215() { # for bugs 18102, 21079, 21517
19030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19031
19032         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19033         local P='[1-9][0-9]*'           # positive numeric
19034         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19035         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19036         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19037         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19038
19039         local L1 # regexp for 1st line
19040         local L2 # regexp for 2nd line (optional)
19041         local BR # regexp for the rest (body)
19042
19043         # lnet.stats should look as 11 space-separated non-negative numerics
19044         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19045         create_lnet_proc_files "stats"
19046         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19047         remove_lnet_proc_files "stats"
19048
19049         # lnet.routes should look like this:
19050         # Routing disabled/enabled
19051         # net hops priority state router
19052         # where net is a string like tcp0, hops > 0, priority >= 0,
19053         # state is up/down,
19054         # router is a string like 192.168.1.1@tcp2
19055         L1="^Routing (disabled|enabled)$"
19056         L2="^net +hops +priority +state +router$"
19057         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19058         create_lnet_proc_files "routes"
19059         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19060         remove_lnet_proc_files "routes"
19061
19062         # lnet.routers should look like this:
19063         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19064         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19065         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19066         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19067         L1="^ref +rtr_ref +alive +router$"
19068         BR="^$P +$P +(up|down) +$NID$"
19069         create_lnet_proc_files "routers"
19070         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19071         remove_lnet_proc_files "routers"
19072
19073         # lnet.peers should look like this:
19074         # nid refs state last max rtr min tx min queue
19075         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19076         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19077         # numeric (0 or >0 or <0), queue >= 0.
19078         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19079         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19080         create_lnet_proc_files "peers"
19081         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19082         remove_lnet_proc_files "peers"
19083
19084         # lnet.buffers  should look like this:
19085         # pages count credits min
19086         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19087         L1="^pages +count +credits +min$"
19088         BR="^ +$N +$N +$I +$I$"
19089         create_lnet_proc_files "buffers"
19090         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19091         remove_lnet_proc_files "buffers"
19092
19093         # lnet.nis should look like this:
19094         # nid status alive refs peer rtr max tx min
19095         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19096         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19097         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19098         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19099         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19100         create_lnet_proc_files "nis"
19101         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19102         remove_lnet_proc_files "nis"
19103
19104         # can we successfully write to lnet.stats?
19105         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19106 }
19107 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19108
19109 test_216() { # bug 20317
19110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19111         remote_ost_nodsh && skip "remote OST with nodsh"
19112
19113         local node
19114         local facets=$(get_facets OST)
19115         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19116
19117         save_lustre_params client "osc.*.contention_seconds" > $p
19118         save_lustre_params $facets \
19119                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19120         save_lustre_params $facets \
19121                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19122         save_lustre_params $facets \
19123                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19124         clear_stats osc.*.osc_stats
19125
19126         # agressive lockless i/o settings
19127         do_nodes $(comma_list $(osts_nodes)) \
19128                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19129                         ldlm.namespaces.filter-*.contended_locks=0 \
19130                         ldlm.namespaces.filter-*.contention_seconds=60"
19131         lctl set_param -n osc.*.contention_seconds=60
19132
19133         $DIRECTIO write $DIR/$tfile 0 10 4096
19134         $CHECKSTAT -s 40960 $DIR/$tfile
19135
19136         # disable lockless i/o
19137         do_nodes $(comma_list $(osts_nodes)) \
19138                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19139                         ldlm.namespaces.filter-*.contended_locks=32 \
19140                         ldlm.namespaces.filter-*.contention_seconds=0"
19141         lctl set_param -n osc.*.contention_seconds=0
19142         clear_stats osc.*.osc_stats
19143
19144         dd if=/dev/zero of=$DIR/$tfile count=0
19145         $CHECKSTAT -s 0 $DIR/$tfile
19146
19147         restore_lustre_params <$p
19148         rm -f $p
19149         rm $DIR/$tfile
19150 }
19151 run_test 216 "check lockless direct write updates file size and kms correctly"
19152
19153 test_217() { # bug 22430
19154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19155
19156         local node
19157         local nid
19158
19159         for node in $(nodes_list); do
19160                 nid=$(host_nids_address $node $NETTYPE)
19161                 if [[ $nid = *-* ]] ; then
19162                         echo "lctl ping $(h2nettype $nid)"
19163                         lctl ping $(h2nettype $nid)
19164                 else
19165                         echo "skipping $node (no hyphen detected)"
19166                 fi
19167         done
19168 }
19169 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19170
19171 test_218() {
19172        # do directio so as not to populate the page cache
19173        log "creating a 10 Mb file"
19174        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19175        log "starting reads"
19176        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19177        log "truncating the file"
19178        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19179        log "killing dd"
19180        kill %+ || true # reads might have finished
19181        echo "wait until dd is finished"
19182        wait
19183        log "removing the temporary file"
19184        rm -rf $DIR/$tfile || error "tmp file removal failed"
19185 }
19186 run_test 218 "parallel read and truncate should not deadlock"
19187
19188 test_219() {
19189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19190
19191         # write one partial page
19192         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19193         # set no grant so vvp_io_commit_write will do sync write
19194         $LCTL set_param fail_loc=0x411
19195         # write a full page at the end of file
19196         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19197
19198         $LCTL set_param fail_loc=0
19199         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19200         $LCTL set_param fail_loc=0x411
19201         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19202
19203         # LU-4201
19204         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19205         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19206 }
19207 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19208
19209 test_220() { #LU-325
19210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19211         remote_ost_nodsh && skip "remote OST with nodsh"
19212         remote_mds_nodsh && skip "remote MDS with nodsh"
19213         remote_mgs_nodsh && skip "remote MGS with nodsh"
19214
19215         local OSTIDX=0
19216
19217         # create on MDT0000 so the last_id and next_id are correct
19218         mkdir_on_mdt0 $DIR/$tdir
19219         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19220         OST=${OST%_UUID}
19221
19222         # on the mdt's osc
19223         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19224         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19225                         osp.$mdtosc_proc1.prealloc_last_id)
19226         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19227                         osp.$mdtosc_proc1.prealloc_next_id)
19228
19229         $LFS df -i
19230
19231         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19232         #define OBD_FAIL_OST_ENOINO              0x229
19233         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19234         create_pool $FSNAME.$TESTNAME || return 1
19235         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19236
19237         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19238
19239         MDSOBJS=$((last_id - next_id))
19240         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19241
19242         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19243         echo "OST still has $count kbytes free"
19244
19245         echo "create $MDSOBJS files @next_id..."
19246         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19247
19248         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19249                         osp.$mdtosc_proc1.prealloc_last_id)
19250         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19251                         osp.$mdtosc_proc1.prealloc_next_id)
19252
19253         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19254         $LFS df -i
19255
19256         echo "cleanup..."
19257
19258         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19259         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19260
19261         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19262                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19263         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19264                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19265         echo "unlink $MDSOBJS files @$next_id..."
19266         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19267 }
19268 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19269
19270 test_221() {
19271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19272
19273         dd if=`which date` of=$MOUNT/date oflag=sync
19274         chmod +x $MOUNT/date
19275
19276         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19277         $LCTL set_param fail_loc=0x80001401
19278
19279         $MOUNT/date > /dev/null
19280         rm -f $MOUNT/date
19281 }
19282 run_test 221 "make sure fault and truncate race to not cause OOM"
19283
19284 test_222a () {
19285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19286
19287         rm -rf $DIR/$tdir
19288         test_mkdir $DIR/$tdir
19289         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19290         createmany -o $DIR/$tdir/$tfile 10
19291         cancel_lru_locks mdc
19292         cancel_lru_locks osc
19293         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19294         $LCTL set_param fail_loc=0x31a
19295         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19296         $LCTL set_param fail_loc=0
19297         rm -r $DIR/$tdir
19298 }
19299 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19300
19301 test_222b () {
19302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19303
19304         rm -rf $DIR/$tdir
19305         test_mkdir $DIR/$tdir
19306         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19307         createmany -o $DIR/$tdir/$tfile 10
19308         cancel_lru_locks mdc
19309         cancel_lru_locks osc
19310         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19311         $LCTL set_param fail_loc=0x31a
19312         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19313         $LCTL set_param fail_loc=0
19314 }
19315 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19316
19317 test_223 () {
19318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19319
19320         rm -rf $DIR/$tdir
19321         test_mkdir $DIR/$tdir
19322         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19323         createmany -o $DIR/$tdir/$tfile 10
19324         cancel_lru_locks mdc
19325         cancel_lru_locks osc
19326         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19327         $LCTL set_param fail_loc=0x31b
19328         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19329         $LCTL set_param fail_loc=0
19330         rm -r $DIR/$tdir
19331 }
19332 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19333
19334 test_224a() { # LU-1039, MRP-303
19335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19336         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19337         $LCTL set_param fail_loc=0x508
19338         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19339         $LCTL set_param fail_loc=0
19340         df $DIR
19341 }
19342 run_test 224a "Don't panic on bulk IO failure"
19343
19344 test_224bd_sub() { # LU-1039, MRP-303
19345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19346         local timeout=$1
19347
19348         shift
19349         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19350
19351         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19352
19353         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19354         cancel_lru_locks osc
19355         set_checksums 0
19356         stack_trap "set_checksums $ORIG_CSUM" EXIT
19357         local at_max_saved=0
19358
19359         # adaptive timeouts may prevent seeing the issue
19360         if at_is_enabled; then
19361                 at_max_saved=$(at_max_get mds)
19362                 at_max_set 0 mds client
19363                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19364         fi
19365
19366         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19367         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19368         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19369
19370         do_facet ost1 $LCTL set_param fail_loc=0
19371         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19372         df $DIR
19373 }
19374
19375 test_224b() {
19376         test_224bd_sub 3 error "dd failed"
19377 }
19378 run_test 224b "Don't panic on bulk IO failure"
19379
19380 test_224c() { # LU-6441
19381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19382         remote_mds_nodsh && skip "remote MDS with nodsh"
19383
19384         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19385         save_writethrough $p
19386         set_cache writethrough on
19387
19388         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19389         local at_max=$($LCTL get_param -n at_max)
19390         local timeout=$($LCTL get_param -n timeout)
19391         local test_at="at_max"
19392         local param_at="$FSNAME.sys.at_max"
19393         local test_timeout="timeout"
19394         local param_timeout="$FSNAME.sys.timeout"
19395
19396         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19397
19398         set_persistent_param_and_check client "$test_at" "$param_at" 0
19399         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19400
19401         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19402         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19403         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19404         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19405         sync
19406         do_facet ost1 "$LCTL set_param fail_loc=0"
19407
19408         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19409         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19410                 $timeout
19411
19412         $LCTL set_param -n $pages_per_rpc
19413         restore_lustre_params < $p
19414         rm -f $p
19415 }
19416 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19417
19418 test_224d() { # LU-11169
19419         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19420 }
19421 run_test 224d "Don't corrupt data on bulk IO timeout"
19422
19423 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19424 test_225a () {
19425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19426         if [ -z ${MDSSURVEY} ]; then
19427                 skip_env "mds-survey not found"
19428         fi
19429         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19430                 skip "Need MDS version at least 2.2.51"
19431
19432         local mds=$(facet_host $SINGLEMDS)
19433         local target=$(do_nodes $mds 'lctl dl' |
19434                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19435
19436         local cmd1="file_count=1000 thrhi=4"
19437         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19438         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19439         local cmd="$cmd1 $cmd2 $cmd3"
19440
19441         rm -f ${TMP}/mds_survey*
19442         echo + $cmd
19443         eval $cmd || error "mds-survey with zero-stripe failed"
19444         cat ${TMP}/mds_survey*
19445         rm -f ${TMP}/mds_survey*
19446 }
19447 run_test 225a "Metadata survey sanity with zero-stripe"
19448
19449 test_225b () {
19450         if [ -z ${MDSSURVEY} ]; then
19451                 skip_env "mds-survey not found"
19452         fi
19453         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19454                 skip "Need MDS version at least 2.2.51"
19455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19456         remote_mds_nodsh && skip "remote MDS with nodsh"
19457         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19458                 skip_env "Need to mount OST to test"
19459         fi
19460
19461         local mds=$(facet_host $SINGLEMDS)
19462         local target=$(do_nodes $mds 'lctl dl' |
19463                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19464
19465         local cmd1="file_count=1000 thrhi=4"
19466         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19467         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19468         local cmd="$cmd1 $cmd2 $cmd3"
19469
19470         rm -f ${TMP}/mds_survey*
19471         echo + $cmd
19472         eval $cmd || error "mds-survey with stripe_count failed"
19473         cat ${TMP}/mds_survey*
19474         rm -f ${TMP}/mds_survey*
19475 }
19476 run_test 225b "Metadata survey sanity with stripe_count = 1"
19477
19478 mcreate_path2fid () {
19479         local mode=$1
19480         local major=$2
19481         local minor=$3
19482         local name=$4
19483         local desc=$5
19484         local path=$DIR/$tdir/$name
19485         local fid
19486         local rc
19487         local fid_path
19488
19489         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19490                 error "cannot create $desc"
19491
19492         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19493         rc=$?
19494         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19495
19496         fid_path=$($LFS fid2path $MOUNT $fid)
19497         rc=$?
19498         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19499
19500         [ "$path" == "$fid_path" ] ||
19501                 error "fid2path returned $fid_path, expected $path"
19502
19503         echo "pass with $path and $fid"
19504 }
19505
19506 test_226a () {
19507         rm -rf $DIR/$tdir
19508         mkdir -p $DIR/$tdir
19509
19510         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19511         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19512         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19513         mcreate_path2fid 0040666 0 0 dir "directory"
19514         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19515         mcreate_path2fid 0100666 0 0 file "regular file"
19516         mcreate_path2fid 0120666 0 0 link "symbolic link"
19517         mcreate_path2fid 0140666 0 0 sock "socket"
19518 }
19519 run_test 226a "call path2fid and fid2path on files of all type"
19520
19521 test_226b () {
19522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19523
19524         local MDTIDX=1
19525
19526         rm -rf $DIR/$tdir
19527         mkdir -p $DIR/$tdir
19528         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19529                 error "create remote directory failed"
19530         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19531         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19532                                 "character special file (null)"
19533         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19534                                 "character special file (no device)"
19535         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19536         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19537                                 "block special file (loop)"
19538         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19539         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19540         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19541 }
19542 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19543
19544 test_226c () {
19545         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19546         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19547                 skip "Need MDS version at least 2.13.55"
19548
19549         local submnt=/mnt/submnt
19550         local srcfile=/etc/passwd
19551         local dstfile=$submnt/passwd
19552         local path
19553         local fid
19554
19555         rm -rf $DIR/$tdir
19556         rm -rf $submnt
19557         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19558                 error "create remote directory failed"
19559         mkdir -p $submnt || error "create $submnt failed"
19560         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19561                 error "mount $submnt failed"
19562         stack_trap "umount $submnt" EXIT
19563
19564         cp $srcfile $dstfile
19565         fid=$($LFS path2fid $dstfile)
19566         path=$($LFS fid2path $submnt "$fid")
19567         [ "$path" = "$dstfile" ] ||
19568                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19569 }
19570 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19571
19572 # LU-1299 Executing or running ldd on a truncated executable does not
19573 # cause an out-of-memory condition.
19574 test_227() {
19575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19576         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19577
19578         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19579         chmod +x $MOUNT/date
19580
19581         $MOUNT/date > /dev/null
19582         ldd $MOUNT/date > /dev/null
19583         rm -f $MOUNT/date
19584 }
19585 run_test 227 "running truncated executable does not cause OOM"
19586
19587 # LU-1512 try to reuse idle OI blocks
19588 test_228a() {
19589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19590         remote_mds_nodsh && skip "remote MDS with nodsh"
19591         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19592
19593         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19594         local myDIR=$DIR/$tdir
19595
19596         mkdir -p $myDIR
19597         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19598         $LCTL set_param fail_loc=0x80001002
19599         createmany -o $myDIR/t- 10000
19600         $LCTL set_param fail_loc=0
19601         # The guard is current the largest FID holder
19602         touch $myDIR/guard
19603         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19604                     tr -d '[')
19605         local IDX=$(($SEQ % 64))
19606
19607         do_facet $SINGLEMDS sync
19608         # Make sure journal flushed.
19609         sleep 6
19610         local blk1=$(do_facet $SINGLEMDS \
19611                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19612                      grep Blockcount | awk '{print $4}')
19613
19614         # Remove old files, some OI blocks will become idle.
19615         unlinkmany $myDIR/t- 10000
19616         # Create new files, idle OI blocks should be reused.
19617         createmany -o $myDIR/t- 2000
19618         do_facet $SINGLEMDS sync
19619         # Make sure journal flushed.
19620         sleep 6
19621         local blk2=$(do_facet $SINGLEMDS \
19622                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19623                      grep Blockcount | awk '{print $4}')
19624
19625         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19626 }
19627 run_test 228a "try to reuse idle OI blocks"
19628
19629 test_228b() {
19630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19631         remote_mds_nodsh && skip "remote MDS with nodsh"
19632         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19633
19634         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19635         local myDIR=$DIR/$tdir
19636
19637         mkdir -p $myDIR
19638         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19639         $LCTL set_param fail_loc=0x80001002
19640         createmany -o $myDIR/t- 10000
19641         $LCTL set_param fail_loc=0
19642         # The guard is current the largest FID holder
19643         touch $myDIR/guard
19644         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19645                     tr -d '[')
19646         local IDX=$(($SEQ % 64))
19647
19648         do_facet $SINGLEMDS sync
19649         # Make sure journal flushed.
19650         sleep 6
19651         local blk1=$(do_facet $SINGLEMDS \
19652                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19653                      grep Blockcount | awk '{print $4}')
19654
19655         # Remove old files, some OI blocks will become idle.
19656         unlinkmany $myDIR/t- 10000
19657
19658         # stop the MDT
19659         stop $SINGLEMDS || error "Fail to stop MDT."
19660         # remount the MDT
19661         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19662                 error "Fail to start MDT."
19663
19664         df $MOUNT || error "Fail to df."
19665         # Create new files, idle OI blocks should be reused.
19666         createmany -o $myDIR/t- 2000
19667         do_facet $SINGLEMDS sync
19668         # Make sure journal flushed.
19669         sleep 6
19670         local blk2=$(do_facet $SINGLEMDS \
19671                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19672                      grep Blockcount | awk '{print $4}')
19673
19674         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19675 }
19676 run_test 228b "idle OI blocks can be reused after MDT restart"
19677
19678 #LU-1881
19679 test_228c() {
19680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19681         remote_mds_nodsh && skip "remote MDS with nodsh"
19682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19683
19684         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19685         local myDIR=$DIR/$tdir
19686
19687         mkdir -p $myDIR
19688         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19689         $LCTL set_param fail_loc=0x80001002
19690         # 20000 files can guarantee there are index nodes in the OI file
19691         createmany -o $myDIR/t- 20000
19692         $LCTL set_param fail_loc=0
19693         # The guard is current the largest FID holder
19694         touch $myDIR/guard
19695         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19696                     tr -d '[')
19697         local IDX=$(($SEQ % 64))
19698
19699         do_facet $SINGLEMDS sync
19700         # Make sure journal flushed.
19701         sleep 6
19702         local blk1=$(do_facet $SINGLEMDS \
19703                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19704                      grep Blockcount | awk '{print $4}')
19705
19706         # Remove old files, some OI blocks will become idle.
19707         unlinkmany $myDIR/t- 20000
19708         rm -f $myDIR/guard
19709         # The OI file should become empty now
19710
19711         # Create new files, idle OI blocks should be reused.
19712         createmany -o $myDIR/t- 2000
19713         do_facet $SINGLEMDS sync
19714         # Make sure journal flushed.
19715         sleep 6
19716         local blk2=$(do_facet $SINGLEMDS \
19717                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19718                      grep Blockcount | awk '{print $4}')
19719
19720         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19721 }
19722 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19723
19724 test_229() { # LU-2482, LU-3448
19725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19726         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19727         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19728                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19729
19730         rm -f $DIR/$tfile
19731
19732         # Create a file with a released layout and stripe count 2.
19733         $MULTIOP $DIR/$tfile H2c ||
19734                 error "failed to create file with released layout"
19735
19736         $LFS getstripe -v $DIR/$tfile
19737
19738         local pattern=$($LFS getstripe -L $DIR/$tfile)
19739         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19740
19741         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19742                 error "getstripe"
19743         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19744         stat $DIR/$tfile || error "failed to stat released file"
19745
19746         chown $RUNAS_ID $DIR/$tfile ||
19747                 error "chown $RUNAS_ID $DIR/$tfile failed"
19748
19749         chgrp $RUNAS_ID $DIR/$tfile ||
19750                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19751
19752         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19753         rm $DIR/$tfile || error "failed to remove released file"
19754 }
19755 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19756
19757 test_230a() {
19758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19759         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19760         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19761                 skip "Need MDS version at least 2.11.52"
19762
19763         local MDTIDX=1
19764
19765         test_mkdir $DIR/$tdir
19766         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19767         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19768         [ $mdt_idx -ne 0 ] &&
19769                 error "create local directory on wrong MDT $mdt_idx"
19770
19771         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19772                         error "create remote directory failed"
19773         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19774         [ $mdt_idx -ne $MDTIDX ] &&
19775                 error "create remote directory on wrong MDT $mdt_idx"
19776
19777         createmany -o $DIR/$tdir/test_230/t- 10 ||
19778                 error "create files on remote directory failed"
19779         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19780         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19781         rm -r $DIR/$tdir || error "unlink remote directory failed"
19782 }
19783 run_test 230a "Create remote directory and files under the remote directory"
19784
19785 test_230b() {
19786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19787         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19788         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19789                 skip "Need MDS version at least 2.11.52"
19790
19791         local MDTIDX=1
19792         local mdt_index
19793         local i
19794         local file
19795         local pid
19796         local stripe_count
19797         local migrate_dir=$DIR/$tdir/migrate_dir
19798         local other_dir=$DIR/$tdir/other_dir
19799
19800         test_mkdir $DIR/$tdir
19801         test_mkdir -i0 -c1 $migrate_dir
19802         test_mkdir -i0 -c1 $other_dir
19803         for ((i=0; i<10; i++)); do
19804                 mkdir -p $migrate_dir/dir_${i}
19805                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19806                         error "create files under remote dir failed $i"
19807         done
19808
19809         cp /etc/passwd $migrate_dir/$tfile
19810         cp /etc/passwd $other_dir/$tfile
19811         chattr +SAD $migrate_dir
19812         chattr +SAD $migrate_dir/$tfile
19813
19814         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19815         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19816         local old_dir_mode=$(stat -c%f $migrate_dir)
19817         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19818
19819         mkdir -p $migrate_dir/dir_default_stripe2
19820         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19821         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19822
19823         mkdir -p $other_dir
19824         ln $migrate_dir/$tfile $other_dir/luna
19825         ln $migrate_dir/$tfile $migrate_dir/sofia
19826         ln $other_dir/$tfile $migrate_dir/david
19827         ln -s $migrate_dir/$tfile $other_dir/zachary
19828         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19829         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19830
19831         local len
19832         local lnktgt
19833
19834         # inline symlink
19835         for len in 58 59 60; do
19836                 lnktgt=$(str_repeat 'l' $len)
19837                 touch $migrate_dir/$lnktgt
19838                 ln -s $lnktgt $migrate_dir/${len}char_ln
19839         done
19840
19841         # PATH_MAX
19842         for len in 4094 4095; do
19843                 lnktgt=$(str_repeat 'l' $len)
19844                 ln -s $lnktgt $migrate_dir/${len}char_ln
19845         done
19846
19847         # NAME_MAX
19848         for len in 254 255; do
19849                 touch $migrate_dir/$(str_repeat 'l' $len)
19850         done
19851
19852         $LFS migrate -m $MDTIDX $migrate_dir ||
19853                 error "fails on migrating remote dir to MDT1"
19854
19855         echo "migratate to MDT1, then checking.."
19856         for ((i = 0; i < 10; i++)); do
19857                 for file in $(find $migrate_dir/dir_${i}); do
19858                         mdt_index=$($LFS getstripe -m $file)
19859                         # broken symlink getstripe will fail
19860                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19861                                 error "$file is not on MDT${MDTIDX}"
19862                 done
19863         done
19864
19865         # the multiple link file should still in MDT0
19866         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19867         [ $mdt_index == 0 ] ||
19868                 error "$file is not on MDT${MDTIDX}"
19869
19870         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19871         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19872                 error " expect $old_dir_flag get $new_dir_flag"
19873
19874         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19875         [ "$old_file_flag" = "$new_file_flag" ] ||
19876                 error " expect $old_file_flag get $new_file_flag"
19877
19878         local new_dir_mode=$(stat -c%f $migrate_dir)
19879         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19880                 error "expect mode $old_dir_mode get $new_dir_mode"
19881
19882         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19883         [ "$old_file_mode" = "$new_file_mode" ] ||
19884                 error "expect mode $old_file_mode get $new_file_mode"
19885
19886         diff /etc/passwd $migrate_dir/$tfile ||
19887                 error "$tfile different after migration"
19888
19889         diff /etc/passwd $other_dir/luna ||
19890                 error "luna different after migration"
19891
19892         diff /etc/passwd $migrate_dir/sofia ||
19893                 error "sofia different after migration"
19894
19895         diff /etc/passwd $migrate_dir/david ||
19896                 error "david different after migration"
19897
19898         diff /etc/passwd $other_dir/zachary ||
19899                 error "zachary different after migration"
19900
19901         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19902                 error "${tfile}_ln different after migration"
19903
19904         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19905                 error "${tfile}_ln_other different after migration"
19906
19907         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19908         [ $stripe_count = 2 ] ||
19909                 error "dir strpe_count $d != 2 after migration."
19910
19911         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19912         [ $stripe_count = 2 ] ||
19913                 error "file strpe_count $d != 2 after migration."
19914
19915         #migrate back to MDT0
19916         MDTIDX=0
19917
19918         $LFS migrate -m $MDTIDX $migrate_dir ||
19919                 error "fails on migrating remote dir to MDT0"
19920
19921         echo "migrate back to MDT0, checking.."
19922         for file in $(find $migrate_dir); do
19923                 mdt_index=$($LFS getstripe -m $file)
19924                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19925                         error "$file is not on MDT${MDTIDX}"
19926         done
19927
19928         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19929         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19930                 error " expect $old_dir_flag get $new_dir_flag"
19931
19932         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19933         [ "$old_file_flag" = "$new_file_flag" ] ||
19934                 error " expect $old_file_flag get $new_file_flag"
19935
19936         local new_dir_mode=$(stat -c%f $migrate_dir)
19937         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19938                 error "expect mode $old_dir_mode get $new_dir_mode"
19939
19940         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19941         [ "$old_file_mode" = "$new_file_mode" ] ||
19942                 error "expect mode $old_file_mode get $new_file_mode"
19943
19944         diff /etc/passwd ${migrate_dir}/$tfile ||
19945                 error "$tfile different after migration"
19946
19947         diff /etc/passwd ${other_dir}/luna ||
19948                 error "luna different after migration"
19949
19950         diff /etc/passwd ${migrate_dir}/sofia ||
19951                 error "sofia different after migration"
19952
19953         diff /etc/passwd ${other_dir}/zachary ||
19954                 error "zachary different after migration"
19955
19956         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19957                 error "${tfile}_ln different after migration"
19958
19959         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19960                 error "${tfile}_ln_other different after migration"
19961
19962         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19963         [ $stripe_count = 2 ] ||
19964                 error "dir strpe_count $d != 2 after migration."
19965
19966         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19967         [ $stripe_count = 2 ] ||
19968                 error "file strpe_count $d != 2 after migration."
19969
19970         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19971 }
19972 run_test 230b "migrate directory"
19973
19974 test_230c() {
19975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19977         remote_mds_nodsh && skip "remote MDS with nodsh"
19978         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19979                 skip "Need MDS version at least 2.11.52"
19980
19981         local MDTIDX=1
19982         local total=3
19983         local mdt_index
19984         local file
19985         local migrate_dir=$DIR/$tdir/migrate_dir
19986
19987         #If migrating directory fails in the middle, all entries of
19988         #the directory is still accessiable.
19989         test_mkdir $DIR/$tdir
19990         test_mkdir -i0 -c1 $migrate_dir
19991         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19992         stat $migrate_dir
19993         createmany -o $migrate_dir/f $total ||
19994                 error "create files under ${migrate_dir} failed"
19995
19996         # fail after migrating top dir, and this will fail only once, so the
19997         # first sub file migration will fail (currently f3), others succeed.
19998         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19999         do_facet mds1 lctl set_param fail_loc=0x1801
20000         local t=$(ls $migrate_dir | wc -l)
20001         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20002                 error "migrate should fail"
20003         local u=$(ls $migrate_dir | wc -l)
20004         [ "$u" == "$t" ] || error "$u != $t during migration"
20005
20006         # add new dir/file should succeed
20007         mkdir $migrate_dir/dir ||
20008                 error "mkdir failed under migrating directory"
20009         touch $migrate_dir/file ||
20010                 error "create file failed under migrating directory"
20011
20012         # add file with existing name should fail
20013         for file in $migrate_dir/f*; do
20014                 stat $file > /dev/null || error "stat $file failed"
20015                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20016                         error "open(O_CREAT|O_EXCL) $file should fail"
20017                 $MULTIOP $file m && error "create $file should fail"
20018                 touch $DIR/$tdir/remote_dir/$tfile ||
20019                         error "touch $tfile failed"
20020                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20021                         error "link $file should fail"
20022                 mdt_index=$($LFS getstripe -m $file)
20023                 if [ $mdt_index == 0 ]; then
20024                         # file failed to migrate is not allowed to rename to
20025                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20026                                 error "rename to $file should fail"
20027                 else
20028                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20029                                 error "rename to $file failed"
20030                 fi
20031                 echo hello >> $file || error "write $file failed"
20032         done
20033
20034         # resume migration with different options should fail
20035         $LFS migrate -m 0 $migrate_dir &&
20036                 error "migrate -m 0 $migrate_dir should fail"
20037
20038         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20039                 error "migrate -c 2 $migrate_dir should fail"
20040
20041         # resume migration should succeed
20042         $LFS migrate -m $MDTIDX $migrate_dir ||
20043                 error "migrate $migrate_dir failed"
20044
20045         echo "Finish migration, then checking.."
20046         for file in $(find $migrate_dir); do
20047                 mdt_index=$($LFS getstripe -m $file)
20048                 [ $mdt_index == $MDTIDX ] ||
20049                         error "$file is not on MDT${MDTIDX}"
20050         done
20051
20052         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20053 }
20054 run_test 230c "check directory accessiblity if migration failed"
20055
20056 test_230d() {
20057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20058         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20059         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20060                 skip "Need MDS version at least 2.11.52"
20061         # LU-11235
20062         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20063
20064         local migrate_dir=$DIR/$tdir/migrate_dir
20065         local old_index
20066         local new_index
20067         local old_count
20068         local new_count
20069         local new_hash
20070         local mdt_index
20071         local i
20072         local j
20073
20074         old_index=$((RANDOM % MDSCOUNT))
20075         old_count=$((MDSCOUNT - old_index))
20076         new_index=$((RANDOM % MDSCOUNT))
20077         new_count=$((MDSCOUNT - new_index))
20078         new_hash=1 # for all_char
20079
20080         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20081         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20082
20083         test_mkdir $DIR/$tdir
20084         test_mkdir -i $old_index -c $old_count $migrate_dir
20085
20086         for ((i=0; i<100; i++)); do
20087                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20088                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20089                         error "create files under remote dir failed $i"
20090         done
20091
20092         echo -n "Migrate from MDT$old_index "
20093         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20094         echo -n "to MDT$new_index"
20095         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20096         echo
20097
20098         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20099         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20100                 error "migrate remote dir error"
20101
20102         echo "Finish migration, then checking.."
20103         for file in $(find $migrate_dir -maxdepth 1); do
20104                 mdt_index=$($LFS getstripe -m $file)
20105                 if [ $mdt_index -lt $new_index ] ||
20106                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20107                         error "$file is on MDT$mdt_index"
20108                 fi
20109         done
20110
20111         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20112 }
20113 run_test 230d "check migrate big directory"
20114
20115 test_230e() {
20116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20118         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20119                 skip "Need MDS version at least 2.11.52"
20120
20121         local i
20122         local j
20123         local a_fid
20124         local b_fid
20125
20126         mkdir_on_mdt0 $DIR/$tdir
20127         mkdir $DIR/$tdir/migrate_dir
20128         mkdir $DIR/$tdir/other_dir
20129         touch $DIR/$tdir/migrate_dir/a
20130         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20131         ls $DIR/$tdir/other_dir
20132
20133         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20134                 error "migrate dir fails"
20135
20136         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20137         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20138
20139         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20140         [ $mdt_index == 0 ] || error "a is not on MDT0"
20141
20142         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20143                 error "migrate dir fails"
20144
20145         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20146         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20147
20148         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20149         [ $mdt_index == 1 ] || error "a is not on MDT1"
20150
20151         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20152         [ $mdt_index == 1 ] || error "b is not on MDT1"
20153
20154         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20155         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20156
20157         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20158
20159         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20160 }
20161 run_test 230e "migrate mulitple local link files"
20162
20163 test_230f() {
20164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20165         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20166         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20167                 skip "Need MDS version at least 2.11.52"
20168
20169         local a_fid
20170         local ln_fid
20171
20172         mkdir -p $DIR/$tdir
20173         mkdir $DIR/$tdir/migrate_dir
20174         $LFS mkdir -i1 $DIR/$tdir/other_dir
20175         touch $DIR/$tdir/migrate_dir/a
20176         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20177         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20178         ls $DIR/$tdir/other_dir
20179
20180         # a should be migrated to MDT1, since no other links on MDT0
20181         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20182                 error "#1 migrate dir fails"
20183         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20184         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20185         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20186         [ $mdt_index == 1 ] || error "a is not on MDT1"
20187
20188         # a should stay on MDT1, because it is a mulitple link file
20189         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20190                 error "#2 migrate dir fails"
20191         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20192         [ $mdt_index == 1 ] || error "a is not on MDT1"
20193
20194         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20195                 error "#3 migrate dir fails"
20196
20197         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20198         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20199         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20200
20201         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20202         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20203
20204         # a should be migrated to MDT0, since no other links on MDT1
20205         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20206                 error "#4 migrate dir fails"
20207         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20208         [ $mdt_index == 0 ] || error "a is not on MDT0"
20209
20210         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20211 }
20212 run_test 230f "migrate mulitple remote link files"
20213
20214 test_230g() {
20215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20216         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20217         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20218                 skip "Need MDS version at least 2.11.52"
20219
20220         mkdir -p $DIR/$tdir/migrate_dir
20221
20222         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20223                 error "migrating dir to non-exist MDT succeeds"
20224         true
20225 }
20226 run_test 230g "migrate dir to non-exist MDT"
20227
20228 test_230h() {
20229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20230         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20231         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20232                 skip "Need MDS version at least 2.11.52"
20233
20234         local mdt_index
20235
20236         mkdir -p $DIR/$tdir/migrate_dir
20237
20238         $LFS migrate -m1 $DIR &&
20239                 error "migrating mountpoint1 should fail"
20240
20241         $LFS migrate -m1 $DIR/$tdir/.. &&
20242                 error "migrating mountpoint2 should fail"
20243
20244         # same as mv
20245         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20246                 error "migrating $tdir/migrate_dir/.. should fail"
20247
20248         true
20249 }
20250 run_test 230h "migrate .. and root"
20251
20252 test_230i() {
20253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20255         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20256                 skip "Need MDS version at least 2.11.52"
20257
20258         mkdir -p $DIR/$tdir/migrate_dir
20259
20260         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20261                 error "migration fails with a tailing slash"
20262
20263         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20264                 error "migration fails with two tailing slashes"
20265 }
20266 run_test 230i "lfs migrate -m tolerates trailing slashes"
20267
20268 test_230j() {
20269         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20270         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20271                 skip "Need MDS version at least 2.11.52"
20272
20273         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20274         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20275                 error "create $tfile failed"
20276         cat /etc/passwd > $DIR/$tdir/$tfile
20277
20278         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20279
20280         cmp /etc/passwd $DIR/$tdir/$tfile ||
20281                 error "DoM file mismatch after migration"
20282 }
20283 run_test 230j "DoM file data not changed after dir migration"
20284
20285 test_230k() {
20286         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20287         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20288                 skip "Need MDS version at least 2.11.56"
20289
20290         local total=20
20291         local files_on_starting_mdt=0
20292
20293         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20294         $LFS getdirstripe $DIR/$tdir
20295         for i in $(seq $total); do
20296                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20297                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20298                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20299         done
20300
20301         echo "$files_on_starting_mdt files on MDT0"
20302
20303         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20304         $LFS getdirstripe $DIR/$tdir
20305
20306         files_on_starting_mdt=0
20307         for i in $(seq $total); do
20308                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20309                         error "file $tfile.$i mismatch after migration"
20310                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20311                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20312         done
20313
20314         echo "$files_on_starting_mdt files on MDT1 after migration"
20315         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20316
20317         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20318         $LFS getdirstripe $DIR/$tdir
20319
20320         files_on_starting_mdt=0
20321         for i in $(seq $total); do
20322                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20323                         error "file $tfile.$i mismatch after 2nd migration"
20324                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20325                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20326         done
20327
20328         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20329         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20330
20331         true
20332 }
20333 run_test 230k "file data not changed after dir migration"
20334
20335 test_230l() {
20336         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20337         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20338                 skip "Need MDS version at least 2.11.56"
20339
20340         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20341         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20342                 error "create files under remote dir failed $i"
20343         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20344 }
20345 run_test 230l "readdir between MDTs won't crash"
20346
20347 test_230m() {
20348         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20349         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20350                 skip "Need MDS version at least 2.11.56"
20351
20352         local MDTIDX=1
20353         local mig_dir=$DIR/$tdir/migrate_dir
20354         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20355         local shortstr="b"
20356         local val
20357
20358         echo "Creating files and dirs with xattrs"
20359         test_mkdir $DIR/$tdir
20360         test_mkdir -i0 -c1 $mig_dir
20361         mkdir $mig_dir/dir
20362         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20363                 error "cannot set xattr attr1 on dir"
20364         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20365                 error "cannot set xattr attr2 on dir"
20366         touch $mig_dir/dir/f0
20367         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20368                 error "cannot set xattr attr1 on file"
20369         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20370                 error "cannot set xattr attr2 on file"
20371         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20372         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20373         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20374         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20375         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20376         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20377         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20378         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20379         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20380
20381         echo "Migrating to MDT1"
20382         $LFS migrate -m $MDTIDX $mig_dir ||
20383                 error "fails on migrating dir to MDT1"
20384
20385         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20386         echo "Checking xattrs"
20387         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20388         [ "$val" = $longstr ] ||
20389                 error "expecting xattr1 $longstr on dir, found $val"
20390         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20391         [ "$val" = $shortstr ] ||
20392                 error "expecting xattr2 $shortstr on dir, found $val"
20393         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20394         [ "$val" = $longstr ] ||
20395                 error "expecting xattr1 $longstr on file, found $val"
20396         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20397         [ "$val" = $shortstr ] ||
20398                 error "expecting xattr2 $shortstr on file, found $val"
20399 }
20400 run_test 230m "xattrs not changed after dir migration"
20401
20402 test_230n() {
20403         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20404         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20405                 skip "Need MDS version at least 2.13.53"
20406
20407         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20408         cat /etc/hosts > $DIR/$tdir/$tfile
20409         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20410         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20411
20412         cmp /etc/hosts $DIR/$tdir/$tfile ||
20413                 error "File data mismatch after migration"
20414 }
20415 run_test 230n "Dir migration with mirrored file"
20416
20417 test_230o() {
20418         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20419         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20420                 skip "Need MDS version at least 2.13.52"
20421
20422         local mdts=$(comma_list $(mdts_nodes))
20423         local timeout=100
20424         local restripe_status
20425         local delta
20426         local i
20427
20428         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20429
20430         # in case "crush" hash type is not set
20431         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20432
20433         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20434                            mdt.*MDT0000.enable_dir_restripe)
20435         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20436         stack_trap "do_nodes $mdts $LCTL set_param \
20437                     mdt.*.enable_dir_restripe=$restripe_status"
20438
20439         mkdir $DIR/$tdir
20440         createmany -m $DIR/$tdir/f 100 ||
20441                 error "create files under remote dir failed $i"
20442         createmany -d $DIR/$tdir/d 100 ||
20443                 error "create dirs under remote dir failed $i"
20444
20445         for i in $(seq 2 $MDSCOUNT); do
20446                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20447                 $LFS setdirstripe -c $i $DIR/$tdir ||
20448                         error "split -c $i $tdir failed"
20449                 wait_update $HOSTNAME \
20450                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20451                         error "dir split not finished"
20452                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20453                         awk '/migrate/ {sum += $2} END { print sum }')
20454                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20455                 # delta is around total_files/stripe_count
20456                 (( $delta < 200 / (i - 1) + 4 )) ||
20457                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20458         done
20459 }
20460 run_test 230o "dir split"
20461
20462 test_230p() {
20463         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20464         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20465                 skip "Need MDS version at least 2.13.52"
20466
20467         local mdts=$(comma_list $(mdts_nodes))
20468         local timeout=100
20469         local restripe_status
20470         local delta
20471         local c
20472
20473         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20474
20475         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20476
20477         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20478                            mdt.*MDT0000.enable_dir_restripe)
20479         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20480         stack_trap "do_nodes $mdts $LCTL set_param \
20481                     mdt.*.enable_dir_restripe=$restripe_status"
20482
20483         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20484         createmany -m $DIR/$tdir/f 100 ||
20485                 error "create files under remote dir failed"
20486         createmany -d $DIR/$tdir/d 100 ||
20487                 error "create dirs under remote dir failed"
20488
20489         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20490                 local mdt_hash="crush"
20491
20492                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20493                 $LFS setdirstripe -c $c $DIR/$tdir ||
20494                         error "split -c $c $tdir failed"
20495                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20496                         mdt_hash="$mdt_hash,fixed"
20497                 elif [ $c -eq 1 ]; then
20498                         mdt_hash="none"
20499                 fi
20500                 wait_update $HOSTNAME \
20501                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20502                         error "dir merge not finished"
20503                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20504                         awk '/migrate/ {sum += $2} END { print sum }')
20505                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20506                 # delta is around total_files/stripe_count
20507                 (( delta < 200 / c + 4 )) ||
20508                         error "$delta files migrated >= $((200 / c + 4))"
20509         done
20510 }
20511 run_test 230p "dir merge"
20512
20513 test_230q() {
20514         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20515         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20516                 skip "Need MDS version at least 2.13.52"
20517
20518         local mdts=$(comma_list $(mdts_nodes))
20519         local saved_threshold=$(do_facet mds1 \
20520                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20521         local saved_delta=$(do_facet mds1 \
20522                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20523         local threshold=100
20524         local delta=2
20525         local total=0
20526         local stripe_count=0
20527         local stripe_index
20528         local nr_files
20529         local create
20530
20531         # test with fewer files on ZFS
20532         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20533
20534         stack_trap "do_nodes $mdts $LCTL set_param \
20535                     mdt.*.dir_split_count=$saved_threshold"
20536         stack_trap "do_nodes $mdts $LCTL set_param \
20537                     mdt.*.dir_split_delta=$saved_delta"
20538         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20539         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20540         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20541         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20542         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20543         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20544
20545         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20546         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20547
20548         create=$((threshold * 3 / 2))
20549         while [ $stripe_count -lt $MDSCOUNT ]; do
20550                 createmany -m $DIR/$tdir/f $total $create ||
20551                         error "create sub files failed"
20552                 stat $DIR/$tdir > /dev/null
20553                 total=$((total + create))
20554                 stripe_count=$((stripe_count + delta))
20555                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20556
20557                 wait_update $HOSTNAME \
20558                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20559                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20560
20561                 wait_update $HOSTNAME \
20562                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20563                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20564
20565                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20566                 echo "$nr_files/$total files on MDT$stripe_index after split"
20567                 # allow 10% margin of imbalance with crush hash
20568                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20569                         error "$nr_files files on MDT$stripe_index after split"
20570
20571                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20572                 [ $nr_files -eq $total ] ||
20573                         error "total sub files $nr_files != $total"
20574         done
20575
20576         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20577
20578         echo "fixed layout directory won't auto split"
20579         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20580         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20581                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20582         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20583                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20584 }
20585 run_test 230q "dir auto split"
20586
20587 test_230r() {
20588         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20589         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20590         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20591                 skip "Need MDS version at least 2.13.54"
20592
20593         # maximum amount of local locks:
20594         # parent striped dir - 2 locks
20595         # new stripe in parent to migrate to - 1 lock
20596         # source and target - 2 locks
20597         # Total 5 locks for regular file
20598         mkdir -p $DIR/$tdir
20599         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20600         touch $DIR/$tdir/dir1/eee
20601
20602         # create 4 hardlink for 4 more locks
20603         # Total: 9 locks > RS_MAX_LOCKS (8)
20604         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20605         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20606         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20607         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20608         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20609         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20610         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20611         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20612
20613         cancel_lru_locks mdc
20614
20615         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20616                 error "migrate dir fails"
20617
20618         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20619 }
20620 run_test 230r "migrate with too many local locks"
20621
20622 test_230s() {
20623         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20624                 skip "Need MDS version at least 2.14.52"
20625
20626         local mdts=$(comma_list $(mdts_nodes))
20627         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20628                                 mdt.*MDT0000.enable_dir_restripe)
20629
20630         stack_trap "do_nodes $mdts $LCTL set_param \
20631                     mdt.*.enable_dir_restripe=$restripe_status"
20632
20633         local st
20634         for st in 0 1; do
20635                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20636                 test_mkdir $DIR/$tdir
20637                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20638                         error "$LFS mkdir should return EEXIST if target exists"
20639                 rmdir $DIR/$tdir
20640         done
20641 }
20642 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20643
20644 test_230t()
20645 {
20646         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20647         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20648                 skip "Need MDS version at least 2.14.50"
20649
20650         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20651         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20652         $LFS project -p 1 -s $DIR/$tdir ||
20653                 error "set $tdir project id failed"
20654         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20655                 error "set subdir project id failed"
20656         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20657 }
20658 run_test 230t "migrate directory with project ID set"
20659
20660 test_230u()
20661 {
20662         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20663         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20664                 skip "Need MDS version at least 2.14.53"
20665
20666         local count
20667
20668         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20669         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20670         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20671         for i in $(seq 0 $((MDSCOUNT - 1))); do
20672                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20673                 echo "$count dirs migrated to MDT$i"
20674         done
20675         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20676         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20677 }
20678 run_test 230u "migrate directory by QOS"
20679
20680 test_230v()
20681 {
20682         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20683         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20684                 skip "Need MDS version at least 2.14.53"
20685
20686         local count
20687
20688         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20689         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20690         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20691         for i in $(seq 0 $((MDSCOUNT - 1))); do
20692                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20693                 echo "$count subdirs migrated to MDT$i"
20694                 (( i == 3 )) && (( count > 0 )) &&
20695                         error "subdir shouldn't be migrated to MDT3"
20696         done
20697         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20698         (( count == 3 )) || error "dirs migrated to $count MDTs"
20699 }
20700 run_test 230v "subdir migrated to the MDT where its parent is located"
20701
20702 test_230w() {
20703         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20704         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20705                 skip "Need MDS version at least 2.14.53"
20706
20707         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20708
20709         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20710                 error "migrate failed"
20711
20712         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20713                 error "$tdir stripe count mismatch"
20714
20715         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20716                 error "$tdir/sub is striped"
20717 }
20718 run_test 230w "non-recursive mode dir migration"
20719
20720 test_231a()
20721 {
20722         # For simplicity this test assumes that max_pages_per_rpc
20723         # is the same across all OSCs
20724         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20725         local bulk_size=$((max_pages * PAGE_SIZE))
20726         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20727                                        head -n 1)
20728
20729         mkdir -p $DIR/$tdir
20730         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20731                 error "failed to set stripe with -S ${brw_size}M option"
20732
20733         # clear the OSC stats
20734         $LCTL set_param osc.*.stats=0 &>/dev/null
20735         stop_writeback
20736
20737         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20738         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20739                 oflag=direct &>/dev/null || error "dd failed"
20740
20741         sync; sleep 1; sync # just to be safe
20742         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20743         if [ x$nrpcs != "x1" ]; then
20744                 $LCTL get_param osc.*.stats
20745                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20746         fi
20747
20748         start_writeback
20749         # Drop the OSC cache, otherwise we will read from it
20750         cancel_lru_locks osc
20751
20752         # clear the OSC stats
20753         $LCTL set_param osc.*.stats=0 &>/dev/null
20754
20755         # Client reads $bulk_size.
20756         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20757                 iflag=direct &>/dev/null || error "dd failed"
20758
20759         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20760         if [ x$nrpcs != "x1" ]; then
20761                 $LCTL get_param osc.*.stats
20762                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20763         fi
20764 }
20765 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20766
20767 test_231b() {
20768         mkdir -p $DIR/$tdir
20769         local i
20770         for i in {0..1023}; do
20771                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20772                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20773                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20774         done
20775         sync
20776 }
20777 run_test 231b "must not assert on fully utilized OST request buffer"
20778
20779 test_232a() {
20780         mkdir -p $DIR/$tdir
20781         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20782
20783         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20784         do_facet ost1 $LCTL set_param fail_loc=0x31c
20785
20786         # ignore dd failure
20787         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20788
20789         do_facet ost1 $LCTL set_param fail_loc=0
20790         umount_client $MOUNT || error "umount failed"
20791         mount_client $MOUNT || error "mount failed"
20792         stop ost1 || error "cannot stop ost1"
20793         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20794 }
20795 run_test 232a "failed lock should not block umount"
20796
20797 test_232b() {
20798         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20799                 skip "Need MDS version at least 2.10.58"
20800
20801         mkdir -p $DIR/$tdir
20802         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20803         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20804         sync
20805         cancel_lru_locks osc
20806
20807         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20808         do_facet ost1 $LCTL set_param fail_loc=0x31c
20809
20810         # ignore failure
20811         $LFS data_version $DIR/$tdir/$tfile || true
20812
20813         do_facet ost1 $LCTL set_param fail_loc=0
20814         umount_client $MOUNT || error "umount failed"
20815         mount_client $MOUNT || error "mount failed"
20816         stop ost1 || error "cannot stop ost1"
20817         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20818 }
20819 run_test 232b "failed data version lock should not block umount"
20820
20821 test_233a() {
20822         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20823                 skip "Need MDS version at least 2.3.64"
20824         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20825
20826         local fid=$($LFS path2fid $MOUNT)
20827
20828         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20829                 error "cannot access $MOUNT using its FID '$fid'"
20830 }
20831 run_test 233a "checking that OBF of the FS root succeeds"
20832
20833 test_233b() {
20834         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20835                 skip "Need MDS version at least 2.5.90"
20836         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20837
20838         local fid=$($LFS path2fid $MOUNT/.lustre)
20839
20840         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20841                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20842
20843         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20844         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20845                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20846 }
20847 run_test 233b "checking that OBF of the FS .lustre succeeds"
20848
20849 test_234() {
20850         local p="$TMP/sanityN-$TESTNAME.parameters"
20851         save_lustre_params client "llite.*.xattr_cache" > $p
20852         lctl set_param llite.*.xattr_cache 1 ||
20853                 skip_env "xattr cache is not supported"
20854
20855         mkdir -p $DIR/$tdir || error "mkdir failed"
20856         touch $DIR/$tdir/$tfile || error "touch failed"
20857         # OBD_FAIL_LLITE_XATTR_ENOMEM
20858         $LCTL set_param fail_loc=0x1405
20859         getfattr -n user.attr $DIR/$tdir/$tfile &&
20860                 error "getfattr should have failed with ENOMEM"
20861         $LCTL set_param fail_loc=0x0
20862         rm -rf $DIR/$tdir
20863
20864         restore_lustre_params < $p
20865         rm -f $p
20866 }
20867 run_test 234 "xattr cache should not crash on ENOMEM"
20868
20869 test_235() {
20870         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20871                 skip "Need MDS version at least 2.4.52"
20872
20873         flock_deadlock $DIR/$tfile
20874         local RC=$?
20875         case $RC in
20876                 0)
20877                 ;;
20878                 124) error "process hangs on a deadlock"
20879                 ;;
20880                 *) error "error executing flock_deadlock $DIR/$tfile"
20881                 ;;
20882         esac
20883 }
20884 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20885
20886 #LU-2935
20887 test_236() {
20888         check_swap_layouts_support
20889
20890         local ref1=/etc/passwd
20891         local ref2=/etc/group
20892         local file1=$DIR/$tdir/f1
20893         local file2=$DIR/$tdir/f2
20894
20895         test_mkdir -c1 $DIR/$tdir
20896         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20897         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20898         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20899         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20900         local fd=$(free_fd)
20901         local cmd="exec $fd<>$file2"
20902         eval $cmd
20903         rm $file2
20904         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20905                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20906         cmd="exec $fd>&-"
20907         eval $cmd
20908         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20909
20910         #cleanup
20911         rm -rf $DIR/$tdir
20912 }
20913 run_test 236 "Layout swap on open unlinked file"
20914
20915 # LU-4659 linkea consistency
20916 test_238() {
20917         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20918                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20919                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20920                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20921
20922         touch $DIR/$tfile
20923         ln $DIR/$tfile $DIR/$tfile.lnk
20924         touch $DIR/$tfile.new
20925         mv $DIR/$tfile.new $DIR/$tfile
20926         local fid1=$($LFS path2fid $DIR/$tfile)
20927         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20928         local path1=$($LFS fid2path $FSNAME "$fid1")
20929         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20930         local path2=$($LFS fid2path $FSNAME "$fid2")
20931         [ $tfile.lnk == $path2 ] ||
20932                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20933         rm -f $DIR/$tfile*
20934 }
20935 run_test 238 "Verify linkea consistency"
20936
20937 test_239A() { # was test_239
20938         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20939                 skip "Need MDS version at least 2.5.60"
20940
20941         local list=$(comma_list $(mdts_nodes))
20942
20943         mkdir -p $DIR/$tdir
20944         createmany -o $DIR/$tdir/f- 5000
20945         unlinkmany $DIR/$tdir/f- 5000
20946         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20947                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20948         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20949                         osp.*MDT*.sync_in_flight" | calc_sum)
20950         [ "$changes" -eq 0 ] || error "$changes not synced"
20951 }
20952 run_test 239A "osp_sync test"
20953
20954 test_239a() { #LU-5297
20955         remote_mds_nodsh && skip "remote MDS with nodsh"
20956
20957         touch $DIR/$tfile
20958         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20959         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20960         chgrp $RUNAS_GID $DIR/$tfile
20961         wait_delete_completed
20962 }
20963 run_test 239a "process invalid osp sync record correctly"
20964
20965 test_239b() { #LU-5297
20966         remote_mds_nodsh && skip "remote MDS with nodsh"
20967
20968         touch $DIR/$tfile1
20969         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20970         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20971         chgrp $RUNAS_GID $DIR/$tfile1
20972         wait_delete_completed
20973         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20974         touch $DIR/$tfile2
20975         chgrp $RUNAS_GID $DIR/$tfile2
20976         wait_delete_completed
20977 }
20978 run_test 239b "process osp sync record with ENOMEM error correctly"
20979
20980 test_240() {
20981         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20982         remote_mds_nodsh && skip "remote MDS with nodsh"
20983
20984         mkdir -p $DIR/$tdir
20985
20986         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20987                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20988         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20989                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20990
20991         umount_client $MOUNT || error "umount failed"
20992         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20993         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20994         mount_client $MOUNT || error "failed to mount client"
20995
20996         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20997         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20998 }
20999 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21000
21001 test_241_bio() {
21002         local count=$1
21003         local bsize=$2
21004
21005         for LOOP in $(seq $count); do
21006                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21007                 cancel_lru_locks $OSC || true
21008         done
21009 }
21010
21011 test_241_dio() {
21012         local count=$1
21013         local bsize=$2
21014
21015         for LOOP in $(seq $1); do
21016                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21017                         2>/dev/null
21018         done
21019 }
21020
21021 test_241a() { # was test_241
21022         local bsize=$PAGE_SIZE
21023
21024         (( bsize < 40960 )) && bsize=40960
21025         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21026         ls -la $DIR/$tfile
21027         cancel_lru_locks $OSC
21028         test_241_bio 1000 $bsize &
21029         PID=$!
21030         test_241_dio 1000 $bsize
21031         wait $PID
21032 }
21033 run_test 241a "bio vs dio"
21034
21035 test_241b() {
21036         local bsize=$PAGE_SIZE
21037
21038         (( bsize < 40960 )) && bsize=40960
21039         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21040         ls -la $DIR/$tfile
21041         test_241_dio 1000 $bsize &
21042         PID=$!
21043         test_241_dio 1000 $bsize
21044         wait $PID
21045 }
21046 run_test 241b "dio vs dio"
21047
21048 test_242() {
21049         remote_mds_nodsh && skip "remote MDS with nodsh"
21050
21051         mkdir_on_mdt0 $DIR/$tdir
21052         touch $DIR/$tdir/$tfile
21053
21054         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21055         do_facet mds1 lctl set_param fail_loc=0x105
21056         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21057
21058         do_facet mds1 lctl set_param fail_loc=0
21059         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21060 }
21061 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21062
21063 test_243()
21064 {
21065         test_mkdir $DIR/$tdir
21066         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21067 }
21068 run_test 243 "various group lock tests"
21069
21070 test_244a()
21071 {
21072         test_mkdir $DIR/$tdir
21073         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21074         sendfile_grouplock $DIR/$tdir/$tfile || \
21075                 error "sendfile+grouplock failed"
21076         rm -rf $DIR/$tdir
21077 }
21078 run_test 244a "sendfile with group lock tests"
21079
21080 test_244b()
21081 {
21082         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21083
21084         local threads=50
21085         local size=$((1024*1024))
21086
21087         test_mkdir $DIR/$tdir
21088         for i in $(seq 1 $threads); do
21089                 local file=$DIR/$tdir/file_$((i / 10))
21090                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21091                 local pids[$i]=$!
21092         done
21093         for i in $(seq 1 $threads); do
21094                 wait ${pids[$i]}
21095         done
21096 }
21097 run_test 244b "multi-threaded write with group lock"
21098
21099 test_245a() {
21100         local flagname="multi_mod_rpcs"
21101         local connect_data_name="max_mod_rpcs"
21102         local out
21103
21104         # check if multiple modify RPCs flag is set
21105         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21106                 grep "connect_flags:")
21107         echo "$out"
21108
21109         echo "$out" | grep -qw $flagname
21110         if [ $? -ne 0 ]; then
21111                 echo "connect flag $flagname is not set"
21112                 return
21113         fi
21114
21115         # check if multiple modify RPCs data is set
21116         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21117         echo "$out"
21118
21119         echo "$out" | grep -qw $connect_data_name ||
21120                 error "import should have connect data $connect_data_name"
21121 }
21122 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21123
21124 test_245b() {
21125         local flagname="multi_mod_rpcs"
21126         local connect_data_name="max_mod_rpcs"
21127         local out
21128
21129         remote_mds_nodsh && skip "remote MDS with nodsh"
21130         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21131
21132         # check if multiple modify RPCs flag is set
21133         out=$(do_facet mds1 \
21134               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21135               grep "connect_flags:")
21136         echo "$out"
21137
21138         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21139
21140         # check if multiple modify RPCs data is set
21141         out=$(do_facet mds1 \
21142               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21143
21144         [[ "$out" =~ $connect_data_name ]] ||
21145                 {
21146                         echo "$out"
21147                         error "missing connect data $connect_data_name"
21148                 }
21149 }
21150 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21151
21152 cleanup_247() {
21153         local submount=$1
21154
21155         trap 0
21156         umount_client $submount
21157         rmdir $submount
21158 }
21159
21160 test_247a() {
21161         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21162                 grep -q subtree ||
21163                 skip_env "Fileset feature is not supported"
21164
21165         local submount=${MOUNT}_$tdir
21166
21167         mkdir $MOUNT/$tdir
21168         mkdir -p $submount || error "mkdir $submount failed"
21169         FILESET="$FILESET/$tdir" mount_client $submount ||
21170                 error "mount $submount failed"
21171         trap "cleanup_247 $submount" EXIT
21172         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21173         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21174                 error "read $MOUNT/$tdir/$tfile failed"
21175         cleanup_247 $submount
21176 }
21177 run_test 247a "mount subdir as fileset"
21178
21179 test_247b() {
21180         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21181                 skip_env "Fileset feature is not supported"
21182
21183         local submount=${MOUNT}_$tdir
21184
21185         rm -rf $MOUNT/$tdir
21186         mkdir -p $submount || error "mkdir $submount failed"
21187         SKIP_FILESET=1
21188         FILESET="$FILESET/$tdir" mount_client $submount &&
21189                 error "mount $submount should fail"
21190         rmdir $submount
21191 }
21192 run_test 247b "mount subdir that dose not exist"
21193
21194 test_247c() {
21195         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21196                 skip_env "Fileset feature is not supported"
21197
21198         local submount=${MOUNT}_$tdir
21199
21200         mkdir -p $MOUNT/$tdir/dir1
21201         mkdir -p $submount || error "mkdir $submount failed"
21202         trap "cleanup_247 $submount" EXIT
21203         FILESET="$FILESET/$tdir" mount_client $submount ||
21204                 error "mount $submount failed"
21205         local fid=$($LFS path2fid $MOUNT/)
21206         $LFS fid2path $submount $fid && error "fid2path should fail"
21207         cleanup_247 $submount
21208 }
21209 run_test 247c "running fid2path outside subdirectory root"
21210
21211 test_247d() {
21212         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21213                 skip "Fileset feature is not supported"
21214
21215         local submount=${MOUNT}_$tdir
21216
21217         mkdir -p $MOUNT/$tdir/dir1
21218         mkdir -p $submount || error "mkdir $submount failed"
21219         FILESET="$FILESET/$tdir" mount_client $submount ||
21220                 error "mount $submount failed"
21221         trap "cleanup_247 $submount" EXIT
21222
21223         local td=$submount/dir1
21224         local fid=$($LFS path2fid $td)
21225         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21226
21227         # check that we get the same pathname back
21228         local rootpath
21229         local found
21230         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21231                 echo "$rootpath $fid"
21232                 found=$($LFS fid2path $rootpath "$fid")
21233                 [ -n "$found" ] || error "fid2path should succeed"
21234                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21235         done
21236         # check wrong root path format
21237         rootpath=$submount"_wrong"
21238         found=$($LFS fid2path $rootpath "$fid")
21239         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21240
21241         cleanup_247 $submount
21242 }
21243 run_test 247d "running fid2path inside subdirectory root"
21244
21245 # LU-8037
21246 test_247e() {
21247         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21248                 grep -q subtree ||
21249                 skip "Fileset feature is not supported"
21250
21251         local submount=${MOUNT}_$tdir
21252
21253         mkdir $MOUNT/$tdir
21254         mkdir -p $submount || error "mkdir $submount failed"
21255         FILESET="$FILESET/.." mount_client $submount &&
21256                 error "mount $submount should fail"
21257         rmdir $submount
21258 }
21259 run_test 247e "mount .. as fileset"
21260
21261 test_247f() {
21262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21263         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21264                 skip "Need at least version 2.13.52"
21265         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21266                 skip "Need at least version 2.14.50"
21267         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21268                 grep -q subtree ||
21269                 skip "Fileset feature is not supported"
21270
21271         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21272         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21273                 error "mkdir remote failed"
21274         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21275                 error "mkdir remote/subdir failed"
21276         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21277                 error "mkdir striped failed"
21278         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21279
21280         local submount=${MOUNT}_$tdir
21281
21282         mkdir -p $submount || error "mkdir $submount failed"
21283         stack_trap "rmdir $submount"
21284
21285         local dir
21286         local stat
21287         local fileset=$FILESET
21288         local mdts=$(comma_list $(mdts_nodes))
21289
21290         stat=$(do_facet mds1 $LCTL get_param -n \
21291                 mdt.*MDT0000.enable_remote_subdir_mount)
21292         stack_trap "do_nodes $mdts $LCTL set_param \
21293                 mdt.*.enable_remote_subdir_mount=$stat"
21294
21295         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21296         stack_trap "umount_client $submount"
21297         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21298                 error "mount remote dir $dir should fail"
21299
21300         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21301                 $tdir/striped/. ; do
21302                 FILESET="$fileset/$dir" mount_client $submount ||
21303                         error "mount $dir failed"
21304                 umount_client $submount
21305         done
21306
21307         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21308         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21309                 error "mount $tdir/remote failed"
21310 }
21311 run_test 247f "mount striped or remote directory as fileset"
21312
21313 test_247g() {
21314         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21315         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21316                 skip "Need at least version 2.14.50"
21317
21318         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21319                 error "mkdir $tdir failed"
21320         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21321
21322         local submount=${MOUNT}_$tdir
21323
21324         mkdir -p $submount || error "mkdir $submount failed"
21325         stack_trap "rmdir $submount"
21326
21327         FILESET="$fileset/$tdir" mount_client $submount ||
21328                 error "mount $dir failed"
21329         stack_trap "umount $submount"
21330
21331         local mdts=$(comma_list $(mdts_nodes))
21332
21333         local nrpcs
21334
21335         stat $submount > /dev/null
21336         cancel_lru_locks $MDC
21337         stat $submount > /dev/null
21338         stat $submount/$tfile > /dev/null
21339         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21340         stat $submount/$tfile > /dev/null
21341         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21342                 awk '/getattr/ {sum += $2} END {print sum}')
21343
21344         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21345 }
21346 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21347
21348 test_248a() {
21349         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21350         [ -z "$fast_read_sav" ] && skip "no fast read support"
21351
21352         # create a large file for fast read verification
21353         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21354
21355         # make sure the file is created correctly
21356         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21357                 { rm -f $DIR/$tfile; skip "file creation error"; }
21358
21359         echo "Test 1: verify that fast read is 4 times faster on cache read"
21360
21361         # small read with fast read enabled
21362         $LCTL set_param -n llite.*.fast_read=1
21363         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21364                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21365                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21366         # small read with fast read disabled
21367         $LCTL set_param -n llite.*.fast_read=0
21368         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21369                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21370                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21371
21372         # verify that fast read is 4 times faster for cache read
21373         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21374                 error_not_in_vm "fast read was not 4 times faster: " \
21375                            "$t_fast vs $t_slow"
21376
21377         echo "Test 2: verify the performance between big and small read"
21378         $LCTL set_param -n llite.*.fast_read=1
21379
21380         # 1k non-cache read
21381         cancel_lru_locks osc
21382         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21383                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21384                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21385
21386         # 1M non-cache read
21387         cancel_lru_locks osc
21388         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21389                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21390                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21391
21392         # verify that big IO is not 4 times faster than small IO
21393         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21394                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21395
21396         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21397         rm -f $DIR/$tfile
21398 }
21399 run_test 248a "fast read verification"
21400
21401 test_248b() {
21402         # Default short_io_bytes=16384, try both smaller and larger sizes.
21403         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21404         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21405         echo "bs=53248 count=113 normal buffered write"
21406         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21407                 error "dd of initial data file failed"
21408         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21409
21410         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21411         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21412                 error "dd with sync normal writes failed"
21413         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21414
21415         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21416         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21417                 error "dd with sync small writes failed"
21418         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21419
21420         cancel_lru_locks osc
21421
21422         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21423         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21424         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21425         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21426                 iflag=direct || error "dd with O_DIRECT small read failed"
21427         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21428         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21429                 error "compare $TMP/$tfile.1 failed"
21430
21431         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21432         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21433
21434         # just to see what the maximum tunable value is, and test parsing
21435         echo "test invalid parameter 2MB"
21436         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21437                 error "too-large short_io_bytes allowed"
21438         echo "test maximum parameter 512KB"
21439         # if we can set a larger short_io_bytes, run test regardless of version
21440         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21441                 # older clients may not allow setting it this large, that's OK
21442                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21443                         skip "Need at least client version 2.13.50"
21444                 error "medium short_io_bytes failed"
21445         fi
21446         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21447         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21448
21449         echo "test large parameter 64KB"
21450         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21451         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21452
21453         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21454         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21455                 error "dd with sync large writes failed"
21456         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21457
21458         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21459         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21460         num=$((113 * 4096 / PAGE_SIZE))
21461         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21462         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21463                 error "dd with O_DIRECT large writes failed"
21464         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21465                 error "compare $DIR/$tfile.3 failed"
21466
21467         cancel_lru_locks osc
21468
21469         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21470         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21471                 error "dd with O_DIRECT large read failed"
21472         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21473                 error "compare $TMP/$tfile.2 failed"
21474
21475         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21476         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21477                 error "dd with O_DIRECT large read failed"
21478         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21479                 error "compare $TMP/$tfile.3 failed"
21480 }
21481 run_test 248b "test short_io read and write for both small and large sizes"
21482
21483 test_249() { # LU-7890
21484         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21485                 skip "Need at least version 2.8.54"
21486
21487         rm -f $DIR/$tfile
21488         $LFS setstripe -c 1 $DIR/$tfile
21489         # Offset 2T == 4k * 512M
21490         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21491                 error "dd to 2T offset failed"
21492 }
21493 run_test 249 "Write above 2T file size"
21494
21495 test_250() {
21496         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21497          && skip "no 16TB file size limit on ZFS"
21498
21499         $LFS setstripe -c 1 $DIR/$tfile
21500         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21501         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21502         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21503         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21504                 conv=notrunc,fsync && error "append succeeded"
21505         return 0
21506 }
21507 run_test 250 "Write above 16T limit"
21508
21509 test_251() {
21510         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21511
21512         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21513         #Skip once - writing the first stripe will succeed
21514         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21515         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21516                 error "short write happened"
21517
21518         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21519         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21520                 error "short read happened"
21521
21522         rm -f $DIR/$tfile
21523 }
21524 run_test 251 "Handling short read and write correctly"
21525
21526 test_252() {
21527         remote_mds_nodsh && skip "remote MDS with nodsh"
21528         remote_ost_nodsh && skip "remote OST with nodsh"
21529         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21530                 skip_env "ldiskfs only test"
21531         fi
21532
21533         local tgt
21534         local dev
21535         local out
21536         local uuid
21537         local num
21538         local gen
21539
21540         # check lr_reader on OST0000
21541         tgt=ost1
21542         dev=$(facet_device $tgt)
21543         out=$(do_facet $tgt $LR_READER $dev)
21544         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21545         echo "$out"
21546         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21547         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21548                 error "Invalid uuid returned by $LR_READER on target $tgt"
21549         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21550
21551         # check lr_reader -c on MDT0000
21552         tgt=mds1
21553         dev=$(facet_device $tgt)
21554         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21555                 skip "$LR_READER does not support additional options"
21556         fi
21557         out=$(do_facet $tgt $LR_READER -c $dev)
21558         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21559         echo "$out"
21560         num=$(echo "$out" | grep -c "mdtlov")
21561         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21562                 error "Invalid number of mdtlov clients returned by $LR_READER"
21563         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21564
21565         # check lr_reader -cr on MDT0000
21566         out=$(do_facet $tgt $LR_READER -cr $dev)
21567         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21568         echo "$out"
21569         echo "$out" | grep -q "^reply_data:$" ||
21570                 error "$LR_READER should have returned 'reply_data' section"
21571         num=$(echo "$out" | grep -c "client_generation")
21572         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21573 }
21574 run_test 252 "check lr_reader tool"
21575
21576 test_253() {
21577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21578         remote_mds_nodsh && skip "remote MDS with nodsh"
21579         remote_mgs_nodsh && skip "remote MGS with nodsh"
21580
21581         local ostidx=0
21582         local rc=0
21583         local ost_name=$(ostname_from_index $ostidx)
21584
21585         # on the mdt's osc
21586         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21587         do_facet $SINGLEMDS $LCTL get_param -n \
21588                 osp.$mdtosc_proc1.reserved_mb_high ||
21589                 skip  "remote MDS does not support reserved_mb_high"
21590
21591         rm -rf $DIR/$tdir
21592         wait_mds_ost_sync
21593         wait_delete_completed
21594         mkdir $DIR/$tdir
21595
21596         pool_add $TESTNAME || error "Pool creation failed"
21597         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21598
21599         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21600                 error "Setstripe failed"
21601
21602         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21603
21604         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21605                     grep "watermarks")
21606         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21607
21608         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21609                         osp.$mdtosc_proc1.prealloc_status)
21610         echo "prealloc_status $oa_status"
21611
21612         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21613                 error "File creation should fail"
21614
21615         #object allocation was stopped, but we still able to append files
21616         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21617                 oflag=append || error "Append failed"
21618
21619         rm -f $DIR/$tdir/$tfile.0
21620
21621         # For this test, we want to delete the files we created to go out of
21622         # space but leave the watermark, so we remain nearly out of space
21623         ost_watermarks_enospc_delete_files $tfile $ostidx
21624
21625         wait_delete_completed
21626
21627         sleep_maxage
21628
21629         for i in $(seq 10 12); do
21630                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21631                         2>/dev/null || error "File creation failed after rm"
21632         done
21633
21634         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21635                         osp.$mdtosc_proc1.prealloc_status)
21636         echo "prealloc_status $oa_status"
21637
21638         if (( oa_status != 0 )); then
21639                 error "Object allocation still disable after rm"
21640         fi
21641 }
21642 run_test 253 "Check object allocation limit"
21643
21644 test_254() {
21645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21646         remote_mds_nodsh && skip "remote MDS with nodsh"
21647
21648         local mdt=$(facet_svc $SINGLEMDS)
21649
21650         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21651                 skip "MDS does not support changelog_size"
21652
21653         local cl_user
21654
21655         changelog_register || error "changelog_register failed"
21656
21657         changelog_clear 0 || error "changelog_clear failed"
21658
21659         local size1=$(do_facet $SINGLEMDS \
21660                       $LCTL get_param -n mdd.$mdt.changelog_size)
21661         echo "Changelog size $size1"
21662
21663         rm -rf $DIR/$tdir
21664         $LFS mkdir -i 0 $DIR/$tdir
21665         # change something
21666         mkdir -p $DIR/$tdir/pics/2008/zachy
21667         touch $DIR/$tdir/pics/2008/zachy/timestamp
21668         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21669         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21670         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21671         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21672         rm $DIR/$tdir/pics/desktop.jpg
21673
21674         local size2=$(do_facet $SINGLEMDS \
21675                       $LCTL get_param -n mdd.$mdt.changelog_size)
21676         echo "Changelog size after work $size2"
21677
21678         (( $size2 > $size1 )) ||
21679                 error "new Changelog size=$size2 less than old size=$size1"
21680 }
21681 run_test 254 "Check changelog size"
21682
21683 ladvise_no_type()
21684 {
21685         local type=$1
21686         local file=$2
21687
21688         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21689                 awk -F: '{print $2}' | grep $type > /dev/null
21690         if [ $? -ne 0 ]; then
21691                 return 0
21692         fi
21693         return 1
21694 }
21695
21696 ladvise_no_ioctl()
21697 {
21698         local file=$1
21699
21700         lfs ladvise -a willread $file > /dev/null 2>&1
21701         if [ $? -eq 0 ]; then
21702                 return 1
21703         fi
21704
21705         lfs ladvise -a willread $file 2>&1 |
21706                 grep "Inappropriate ioctl for device" > /dev/null
21707         if [ $? -eq 0 ]; then
21708                 return 0
21709         fi
21710         return 1
21711 }
21712
21713 percent() {
21714         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21715 }
21716
21717 # run a random read IO workload
21718 # usage: random_read_iops <filename> <filesize> <iosize>
21719 random_read_iops() {
21720         local file=$1
21721         local fsize=$2
21722         local iosize=${3:-4096}
21723
21724         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21725                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21726 }
21727
21728 drop_file_oss_cache() {
21729         local file="$1"
21730         local nodes="$2"
21731
21732         $LFS ladvise -a dontneed $file 2>/dev/null ||
21733                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21734 }
21735
21736 ladvise_willread_performance()
21737 {
21738         local repeat=10
21739         local average_origin=0
21740         local average_cache=0
21741         local average_ladvise=0
21742
21743         for ((i = 1; i <= $repeat; i++)); do
21744                 echo "Iter $i/$repeat: reading without willread hint"
21745                 cancel_lru_locks osc
21746                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21747                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21748                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21749                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21750
21751                 cancel_lru_locks osc
21752                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21753                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21754                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21755
21756                 cancel_lru_locks osc
21757                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21758                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21759                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21760                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21761                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21762         done
21763         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21764         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21765         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21766
21767         speedup_cache=$(percent $average_cache $average_origin)
21768         speedup_ladvise=$(percent $average_ladvise $average_origin)
21769
21770         echo "Average uncached read: $average_origin"
21771         echo "Average speedup with OSS cached read: " \
21772                 "$average_cache = +$speedup_cache%"
21773         echo "Average speedup with ladvise willread: " \
21774                 "$average_ladvise = +$speedup_ladvise%"
21775
21776         local lowest_speedup=20
21777         if (( ${average_cache%.*} < $lowest_speedup )); then
21778                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21779                      " got $average_cache%. Skipping ladvise willread check."
21780                 return 0
21781         fi
21782
21783         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21784         # it is still good to run until then to exercise 'ladvise willread'
21785         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21786                 [ "$ost1_FSTYPE" = "zfs" ] &&
21787                 echo "osd-zfs does not support dontneed or drop_caches" &&
21788                 return 0
21789
21790         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21791         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21792                 error_not_in_vm "Speedup with willread is less than " \
21793                         "$lowest_speedup%, got $average_ladvise%"
21794 }
21795
21796 test_255a() {
21797         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21798                 skip "lustre < 2.8.54 does not support ladvise "
21799         remote_ost_nodsh && skip "remote OST with nodsh"
21800
21801         stack_trap "rm -f $DIR/$tfile"
21802         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21803
21804         ladvise_no_type willread $DIR/$tfile &&
21805                 skip "willread ladvise is not supported"
21806
21807         ladvise_no_ioctl $DIR/$tfile &&
21808                 skip "ladvise ioctl is not supported"
21809
21810         local size_mb=100
21811         local size=$((size_mb * 1048576))
21812         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21813                 error "dd to $DIR/$tfile failed"
21814
21815         lfs ladvise -a willread $DIR/$tfile ||
21816                 error "Ladvise failed with no range argument"
21817
21818         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21819                 error "Ladvise failed with no -l or -e argument"
21820
21821         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21822                 error "Ladvise failed with only -e argument"
21823
21824         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21825                 error "Ladvise failed with only -l argument"
21826
21827         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21828                 error "End offset should not be smaller than start offset"
21829
21830         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21831                 error "End offset should not be equal to start offset"
21832
21833         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21834                 error "Ladvise failed with overflowing -s argument"
21835
21836         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21837                 error "Ladvise failed with overflowing -e argument"
21838
21839         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21840                 error "Ladvise failed with overflowing -l argument"
21841
21842         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21843                 error "Ladvise succeeded with conflicting -l and -e arguments"
21844
21845         echo "Synchronous ladvise should wait"
21846         local delay=4
21847 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21848         do_nodes $(comma_list $(osts_nodes)) \
21849                 $LCTL set_param fail_val=$delay fail_loc=0x237
21850
21851         local start_ts=$SECONDS
21852         lfs ladvise -a willread $DIR/$tfile ||
21853                 error "Ladvise failed with no range argument"
21854         local end_ts=$SECONDS
21855         local inteval_ts=$((end_ts - start_ts))
21856
21857         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21858                 error "Synchronous advice didn't wait reply"
21859         fi
21860
21861         echo "Asynchronous ladvise shouldn't wait"
21862         local start_ts=$SECONDS
21863         lfs ladvise -a willread -b $DIR/$tfile ||
21864                 error "Ladvise failed with no range argument"
21865         local end_ts=$SECONDS
21866         local inteval_ts=$((end_ts - start_ts))
21867
21868         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21869                 error "Asynchronous advice blocked"
21870         fi
21871
21872         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21873         ladvise_willread_performance
21874 }
21875 run_test 255a "check 'lfs ladvise -a willread'"
21876
21877 facet_meminfo() {
21878         local facet=$1
21879         local info=$2
21880
21881         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21882 }
21883
21884 test_255b() {
21885         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21886                 skip "lustre < 2.8.54 does not support ladvise "
21887         remote_ost_nodsh && skip "remote OST with nodsh"
21888
21889         stack_trap "rm -f $DIR/$tfile"
21890         lfs setstripe -c 1 -i 0 $DIR/$tfile
21891
21892         ladvise_no_type dontneed $DIR/$tfile &&
21893                 skip "dontneed ladvise is not supported"
21894
21895         ladvise_no_ioctl $DIR/$tfile &&
21896                 skip "ladvise ioctl is not supported"
21897
21898         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21899                 [ "$ost1_FSTYPE" = "zfs" ] &&
21900                 skip "zfs-osd does not support 'ladvise dontneed'"
21901
21902         local size_mb=100
21903         local size=$((size_mb * 1048576))
21904         # In order to prevent disturbance of other processes, only check 3/4
21905         # of the memory usage
21906         local kibibytes=$((size_mb * 1024 * 3 / 4))
21907
21908         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21909                 error "dd to $DIR/$tfile failed"
21910
21911         #force write to complete before dropping OST cache & checking memory
21912         sync
21913
21914         local total=$(facet_meminfo ost1 MemTotal)
21915         echo "Total memory: $total KiB"
21916
21917         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21918         local before_read=$(facet_meminfo ost1 Cached)
21919         echo "Cache used before read: $before_read KiB"
21920
21921         lfs ladvise -a willread $DIR/$tfile ||
21922                 error "Ladvise willread failed"
21923         local after_read=$(facet_meminfo ost1 Cached)
21924         echo "Cache used after read: $after_read KiB"
21925
21926         lfs ladvise -a dontneed $DIR/$tfile ||
21927                 error "Ladvise dontneed again failed"
21928         local no_read=$(facet_meminfo ost1 Cached)
21929         echo "Cache used after dontneed ladvise: $no_read KiB"
21930
21931         if [ $total -lt $((before_read + kibibytes)) ]; then
21932                 echo "Memory is too small, abort checking"
21933                 return 0
21934         fi
21935
21936         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21937                 error "Ladvise willread should use more memory" \
21938                         "than $kibibytes KiB"
21939         fi
21940
21941         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21942                 error "Ladvise dontneed should release more memory" \
21943                         "than $kibibytes KiB"
21944         fi
21945 }
21946 run_test 255b "check 'lfs ladvise -a dontneed'"
21947
21948 test_255c() {
21949         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21950                 skip "lustre < 2.10.50 does not support lockahead"
21951
21952         local ost1_imp=$(get_osc_import_name client ost1)
21953         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21954                          cut -d'.' -f2)
21955         local count
21956         local new_count
21957         local difference
21958         local i
21959         local rc
21960
21961         test_mkdir -p $DIR/$tdir
21962         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21963
21964         #test 10 returns only success/failure
21965         i=10
21966         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21967         rc=$?
21968         if [ $rc -eq 255 ]; then
21969                 error "Ladvise test${i} failed, ${rc}"
21970         fi
21971
21972         #test 11 counts lock enqueue requests, all others count new locks
21973         i=11
21974         count=$(do_facet ost1 \
21975                 $LCTL get_param -n ost.OSS.ost.stats)
21976         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21977
21978         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21979         rc=$?
21980         if [ $rc -eq 255 ]; then
21981                 error "Ladvise test${i} failed, ${rc}"
21982         fi
21983
21984         new_count=$(do_facet ost1 \
21985                 $LCTL get_param -n ost.OSS.ost.stats)
21986         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21987                    awk '{ print $2 }')
21988
21989         difference="$((new_count - count))"
21990         if [ $difference -ne $rc ]; then
21991                 error "Ladvise test${i}, bad enqueue count, returned " \
21992                       "${rc}, actual ${difference}"
21993         fi
21994
21995         for i in $(seq 12 21); do
21996                 # If we do not do this, we run the risk of having too many
21997                 # locks and starting lock cancellation while we are checking
21998                 # lock counts.
21999                 cancel_lru_locks osc
22000
22001                 count=$($LCTL get_param -n \
22002                        ldlm.namespaces.$imp_name.lock_unused_count)
22003
22004                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22005                 rc=$?
22006                 if [ $rc -eq 255 ]; then
22007                         error "Ladvise test ${i} failed, ${rc}"
22008                 fi
22009
22010                 new_count=$($LCTL get_param -n \
22011                        ldlm.namespaces.$imp_name.lock_unused_count)
22012                 difference="$((new_count - count))"
22013
22014                 # Test 15 output is divided by 100 to map down to valid return
22015                 if [ $i -eq 15 ]; then
22016                         rc="$((rc * 100))"
22017                 fi
22018
22019                 if [ $difference -ne $rc ]; then
22020                         error "Ladvise test ${i}, bad lock count, returned " \
22021                               "${rc}, actual ${difference}"
22022                 fi
22023         done
22024
22025         #test 22 returns only success/failure
22026         i=22
22027         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22028         rc=$?
22029         if [ $rc -eq 255 ]; then
22030                 error "Ladvise test${i} failed, ${rc}"
22031         fi
22032 }
22033 run_test 255c "suite of ladvise lockahead tests"
22034
22035 test_256() {
22036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22037         remote_mds_nodsh && skip "remote MDS with nodsh"
22038         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22039         changelog_users $SINGLEMDS | grep "^cl" &&
22040                 skip "active changelog user"
22041
22042         local cl_user
22043         local cat_sl
22044         local mdt_dev
22045
22046         mdt_dev=$(facet_device $SINGLEMDS)
22047         echo $mdt_dev
22048
22049         changelog_register || error "changelog_register failed"
22050
22051         rm -rf $DIR/$tdir
22052         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22053
22054         changelog_clear 0 || error "changelog_clear failed"
22055
22056         # change something
22057         touch $DIR/$tdir/{1..10}
22058
22059         # stop the MDT
22060         stop $SINGLEMDS || error "Fail to stop MDT"
22061
22062         # remount the MDT
22063         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22064                 error "Fail to start MDT"
22065
22066         #after mount new plainllog is used
22067         touch $DIR/$tdir/{11..19}
22068         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22069         stack_trap "rm -f $tmpfile"
22070         cat_sl=$(do_facet $SINGLEMDS "sync; \
22071                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22072                  llog_reader $tmpfile | grep -c type=1064553b")
22073         do_facet $SINGLEMDS llog_reader $tmpfile
22074
22075         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22076
22077         changelog_clear 0 || error "changelog_clear failed"
22078
22079         cat_sl=$(do_facet $SINGLEMDS "sync; \
22080                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22081                  llog_reader $tmpfile | grep -c type=1064553b")
22082
22083         if (( cat_sl == 2 )); then
22084                 error "Empty plain llog was not deleted from changelog catalog"
22085         elif (( cat_sl != 1 )); then
22086                 error "Active plain llog shouldn't be deleted from catalog"
22087         fi
22088 }
22089 run_test 256 "Check llog delete for empty and not full state"
22090
22091 test_257() {
22092         remote_mds_nodsh && skip "remote MDS with nodsh"
22093         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22094                 skip "Need MDS version at least 2.8.55"
22095
22096         test_mkdir $DIR/$tdir
22097
22098         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22099                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22100         stat $DIR/$tdir
22101
22102 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22103         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22104         local facet=mds$((mdtidx + 1))
22105         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22106         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22107
22108         stop $facet || error "stop MDS failed"
22109         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22110                 error "start MDS fail"
22111         wait_recovery_complete $facet
22112 }
22113 run_test 257 "xattr locks are not lost"
22114
22115 # Verify we take the i_mutex when security requires it
22116 test_258a() {
22117 #define OBD_FAIL_IMUTEX_SEC 0x141c
22118         $LCTL set_param fail_loc=0x141c
22119         touch $DIR/$tfile
22120         chmod u+s $DIR/$tfile
22121         chmod a+rwx $DIR/$tfile
22122         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22123         RC=$?
22124         if [ $RC -ne 0 ]; then
22125                 error "error, failed to take i_mutex, rc=$?"
22126         fi
22127         rm -f $DIR/$tfile
22128 }
22129 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22130
22131 # Verify we do NOT take the i_mutex in the normal case
22132 test_258b() {
22133 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22134         $LCTL set_param fail_loc=0x141d
22135         touch $DIR/$tfile
22136         chmod a+rwx $DIR
22137         chmod a+rw $DIR/$tfile
22138         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22139         RC=$?
22140         if [ $RC -ne 0 ]; then
22141                 error "error, took i_mutex unnecessarily, rc=$?"
22142         fi
22143         rm -f $DIR/$tfile
22144
22145 }
22146 run_test 258b "verify i_mutex security behavior"
22147
22148 test_259() {
22149         local file=$DIR/$tfile
22150         local before
22151         local after
22152
22153         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22154
22155         stack_trap "rm -f $file" EXIT
22156
22157         wait_delete_completed
22158         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22159         echo "before: $before"
22160
22161         $LFS setstripe -i 0 -c 1 $file
22162         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22163         sync_all_data
22164         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22165         echo "after write: $after"
22166
22167 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22168         do_facet ost1 $LCTL set_param fail_loc=0x2301
22169         $TRUNCATE $file 0
22170         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22171         echo "after truncate: $after"
22172
22173         stop ost1
22174         do_facet ost1 $LCTL set_param fail_loc=0
22175         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22176         sleep 2
22177         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22178         echo "after restart: $after"
22179         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22180                 error "missing truncate?"
22181
22182         return 0
22183 }
22184 run_test 259 "crash at delayed truncate"
22185
22186 test_260() {
22187 #define OBD_FAIL_MDC_CLOSE               0x806
22188         $LCTL set_param fail_loc=0x80000806
22189         touch $DIR/$tfile
22190
22191 }
22192 run_test 260 "Check mdc_close fail"
22193
22194 ### Data-on-MDT sanity tests ###
22195 test_270a() {
22196         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22197                 skip "Need MDS version at least 2.10.55 for DoM"
22198
22199         # create DoM file
22200         local dom=$DIR/$tdir/dom_file
22201         local tmp=$DIR/$tdir/tmp_file
22202
22203         mkdir_on_mdt0 $DIR/$tdir
22204
22205         # basic checks for DoM component creation
22206         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22207                 error "Can set MDT layout to non-first entry"
22208
22209         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22210                 error "Can define multiple entries as MDT layout"
22211
22212         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22213
22214         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22215         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22216         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22217
22218         local mdtidx=$($LFS getstripe -m $dom)
22219         local mdtname=MDT$(printf %04x $mdtidx)
22220         local facet=mds$((mdtidx + 1))
22221         local space_check=1
22222
22223         # Skip free space checks with ZFS
22224         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22225
22226         # write
22227         sync
22228         local size_tmp=$((65536 * 3))
22229         local mdtfree1=$(do_facet $facet \
22230                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22231
22232         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22233         # check also direct IO along write
22234         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22235         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22236         sync
22237         cmp $tmp $dom || error "file data is different"
22238         [ $(stat -c%s $dom) == $size_tmp ] ||
22239                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22240         if [ $space_check == 1 ]; then
22241                 local mdtfree2=$(do_facet $facet \
22242                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22243
22244                 # increase in usage from by $size_tmp
22245                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22246                         error "MDT free space wrong after write: " \
22247                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22248         fi
22249
22250         # truncate
22251         local size_dom=10000
22252
22253         $TRUNCATE $dom $size_dom
22254         [ $(stat -c%s $dom) == $size_dom ] ||
22255                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22256         if [ $space_check == 1 ]; then
22257                 mdtfree1=$(do_facet $facet \
22258                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22259                 # decrease in usage from $size_tmp to new $size_dom
22260                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22261                   $(((size_tmp - size_dom) / 1024)) ] ||
22262                         error "MDT free space is wrong after truncate: " \
22263                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22264         fi
22265
22266         # append
22267         cat $tmp >> $dom
22268         sync
22269         size_dom=$((size_dom + size_tmp))
22270         [ $(stat -c%s $dom) == $size_dom ] ||
22271                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22272         if [ $space_check == 1 ]; then
22273                 mdtfree2=$(do_facet $facet \
22274                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22275                 # increase in usage by $size_tmp from previous
22276                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22277                         error "MDT free space is wrong after append: " \
22278                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22279         fi
22280
22281         # delete
22282         rm $dom
22283         if [ $space_check == 1 ]; then
22284                 mdtfree1=$(do_facet $facet \
22285                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22286                 # decrease in usage by $size_dom from previous
22287                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22288                         error "MDT free space is wrong after removal: " \
22289                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22290         fi
22291
22292         # combined striping
22293         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22294                 error "Can't create DoM + OST striping"
22295
22296         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22297         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22298         # check also direct IO along write
22299         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22300         sync
22301         cmp $tmp $dom || error "file data is different"
22302         [ $(stat -c%s $dom) == $size_tmp ] ||
22303                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22304         rm $dom $tmp
22305
22306         return 0
22307 }
22308 run_test 270a "DoM: basic functionality tests"
22309
22310 test_270b() {
22311         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22312                 skip "Need MDS version at least 2.10.55"
22313
22314         local dom=$DIR/$tdir/dom_file
22315         local max_size=1048576
22316
22317         mkdir -p $DIR/$tdir
22318         $LFS setstripe -E $max_size -L mdt $dom
22319
22320         # truncate over the limit
22321         $TRUNCATE $dom $(($max_size + 1)) &&
22322                 error "successful truncate over the maximum size"
22323         # write over the limit
22324         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22325                 error "successful write over the maximum size"
22326         # append over the limit
22327         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22328         echo "12345" >> $dom && error "successful append over the maximum size"
22329         rm $dom
22330
22331         return 0
22332 }
22333 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22334
22335 test_270c() {
22336         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22337                 skip "Need MDS version at least 2.10.55"
22338
22339         mkdir -p $DIR/$tdir
22340         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22341
22342         # check files inherit DoM EA
22343         touch $DIR/$tdir/first
22344         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22345                 error "bad pattern"
22346         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22347                 error "bad stripe count"
22348         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22349                 error "bad stripe size"
22350
22351         # check directory inherits DoM EA and uses it as default
22352         mkdir $DIR/$tdir/subdir
22353         touch $DIR/$tdir/subdir/second
22354         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22355                 error "bad pattern in sub-directory"
22356         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22357                 error "bad stripe count in sub-directory"
22358         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22359                 error "bad stripe size in sub-directory"
22360         return 0
22361 }
22362 run_test 270c "DoM: DoM EA inheritance tests"
22363
22364 test_270d() {
22365         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22366                 skip "Need MDS version at least 2.10.55"
22367
22368         mkdir -p $DIR/$tdir
22369         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22370
22371         # inherit default DoM striping
22372         mkdir $DIR/$tdir/subdir
22373         touch $DIR/$tdir/subdir/f1
22374
22375         # change default directory striping
22376         $LFS setstripe -c 1 $DIR/$tdir/subdir
22377         touch $DIR/$tdir/subdir/f2
22378         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22379                 error "wrong default striping in file 2"
22380         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22381                 error "bad pattern in file 2"
22382         return 0
22383 }
22384 run_test 270d "DoM: change striping from DoM to RAID0"
22385
22386 test_270e() {
22387         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22388                 skip "Need MDS version at least 2.10.55"
22389
22390         mkdir -p $DIR/$tdir/dom
22391         mkdir -p $DIR/$tdir/norm
22392         DOMFILES=20
22393         NORMFILES=10
22394         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22395         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22396
22397         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22398         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22399
22400         # find DoM files by layout
22401         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22402         [ $NUM -eq  $DOMFILES ] ||
22403                 error "lfs find -L: found $NUM, expected $DOMFILES"
22404         echo "Test 1: lfs find 20 DOM files by layout: OK"
22405
22406         # there should be 1 dir with default DOM striping
22407         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22408         [ $NUM -eq  1 ] ||
22409                 error "lfs find -L: found $NUM, expected 1 dir"
22410         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22411
22412         # find DoM files by stripe size
22413         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22414         [ $NUM -eq  $DOMFILES ] ||
22415                 error "lfs find -S: found $NUM, expected $DOMFILES"
22416         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22417
22418         # find files by stripe offset except DoM files
22419         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22420         [ $NUM -eq  $NORMFILES ] ||
22421                 error "lfs find -i: found $NUM, expected $NORMFILES"
22422         echo "Test 5: lfs find no DOM files by stripe index: OK"
22423         return 0
22424 }
22425 run_test 270e "DoM: lfs find with DoM files test"
22426
22427 test_270f() {
22428         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22429                 skip "Need MDS version at least 2.10.55"
22430
22431         local mdtname=${FSNAME}-MDT0000-mdtlov
22432         local dom=$DIR/$tdir/dom_file
22433         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22434                                                 lod.$mdtname.dom_stripesize)
22435         local dom_limit=131072
22436
22437         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22438         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22439                                                 lod.$mdtname.dom_stripesize)
22440         [ ${dom_limit} -eq ${dom_current} ] ||
22441                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22442
22443         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22444         $LFS setstripe -d $DIR/$tdir
22445         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22446                 error "Can't set directory default striping"
22447
22448         # exceed maximum stripe size
22449         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22450                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22451         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22452                 error "Able to create DoM component size more than LOD limit"
22453
22454         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22455         dom_current=$(do_facet mds1 $LCTL get_param -n \
22456                                                 lod.$mdtname.dom_stripesize)
22457         [ 0 -eq ${dom_current} ] ||
22458                 error "Can't set zero DoM stripe limit"
22459         rm $dom
22460
22461         # attempt to create DoM file on server with disabled DoM should
22462         # remove DoM entry from layout and be succeed
22463         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22464                 error "Can't create DoM file (DoM is disabled)"
22465         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22466                 error "File has DoM component while DoM is disabled"
22467         rm $dom
22468
22469         # attempt to create DoM file with only DoM stripe should return error
22470         $LFS setstripe -E $dom_limit -L mdt $dom &&
22471                 error "Able to create DoM-only file while DoM is disabled"
22472
22473         # too low values to be aligned with smallest stripe size 64K
22474         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22475         dom_current=$(do_facet mds1 $LCTL get_param -n \
22476                                                 lod.$mdtname.dom_stripesize)
22477         [ 30000 -eq ${dom_current} ] &&
22478                 error "Can set too small DoM stripe limit"
22479
22480         # 64K is a minimal stripe size in Lustre, expect limit of that size
22481         [ 65536 -eq ${dom_current} ] ||
22482                 error "Limit is not set to 64K but ${dom_current}"
22483
22484         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22485         dom_current=$(do_facet mds1 $LCTL get_param -n \
22486                                                 lod.$mdtname.dom_stripesize)
22487         echo $dom_current
22488         [ 2147483648 -eq ${dom_current} ] &&
22489                 error "Can set too large DoM stripe limit"
22490
22491         do_facet mds1 $LCTL set_param -n \
22492                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22493         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22494                 error "Can't create DoM component size after limit change"
22495         do_facet mds1 $LCTL set_param -n \
22496                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22497         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22498                 error "Can't create DoM file after limit decrease"
22499         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22500                 error "Can create big DoM component after limit decrease"
22501         touch ${dom}_def ||
22502                 error "Can't create file with old default layout"
22503
22504         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22505         return 0
22506 }
22507 run_test 270f "DoM: maximum DoM stripe size checks"
22508
22509 test_270g() {
22510         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22511                 skip "Need MDS version at least 2.13.52"
22512         local dom=$DIR/$tdir/$tfile
22513
22514         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22515         local lodname=${FSNAME}-MDT0000-mdtlov
22516
22517         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22518         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22519         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22520         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22521
22522         local dom_limit=1024
22523         local dom_threshold="50%"
22524
22525         $LFS setstripe -d $DIR/$tdir
22526         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22527                 error "Can't set directory default striping"
22528
22529         do_facet mds1 $LCTL set_param -n \
22530                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22531         # set 0 threshold and create DOM file to change tunable stripesize
22532         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22533         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22534                 error "Failed to create $dom file"
22535         # now tunable dom_cur_stripesize should reach maximum
22536         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22537                                         lod.${lodname}.dom_stripesize_cur_kb)
22538         [[ $dom_current == $dom_limit ]] ||
22539                 error "Current DOM stripesize is not maximum"
22540         rm $dom
22541
22542         # set threshold for further tests
22543         do_facet mds1 $LCTL set_param -n \
22544                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22545         echo "DOM threshold is $dom_threshold free space"
22546         local dom_def
22547         local dom_set
22548         # Spoof bfree to exceed threshold
22549         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22550         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22551         for spfree in 40 20 0 15 30 55; do
22552                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22553                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22554                         error "Failed to create $dom file"
22555                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22556                                         lod.${lodname}.dom_stripesize_cur_kb)
22557                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22558                 [[ $dom_def != $dom_current ]] ||
22559                         error "Default stripe size was not changed"
22560                 if (( spfree > 0 )) ; then
22561                         dom_set=$($LFS getstripe -S $dom)
22562                         (( dom_set == dom_def * 1024 )) ||
22563                                 error "DOM component size is still old"
22564                 else
22565                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22566                                 error "DoM component is set with no free space"
22567                 fi
22568                 rm $dom
22569                 dom_current=$dom_def
22570         done
22571 }
22572 run_test 270g "DoM: default DoM stripe size depends on free space"
22573
22574 test_270h() {
22575         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22576                 skip "Need MDS version at least 2.13.53"
22577
22578         local mdtname=${FSNAME}-MDT0000-mdtlov
22579         local dom=$DIR/$tdir/$tfile
22580         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22581
22582         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22583         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22584
22585         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22586         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22587                 error "can't create OST file"
22588         # mirrored file with DOM entry in the second mirror
22589         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22590                 error "can't create mirror with DoM component"
22591
22592         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22593
22594         # DOM component in the middle and has other enries in the same mirror,
22595         # should succeed but lost DoM component
22596         $LFS setstripe --copy=${dom}_1 $dom ||
22597                 error "Can't create file from OST|DOM mirror layout"
22598         # check new file has no DoM layout after all
22599         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22600                 error "File has DoM component while DoM is disabled"
22601 }
22602 run_test 270h "DoM: DoM stripe removal when disabled on server"
22603
22604 test_270i() {
22605         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22606                 skip "Need MDS version at least 2.14.54"
22607
22608         mkdir $DIR/$tdir
22609         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22610                 error "setstripe should fail" || true
22611 }
22612 run_test 270i "DoM: setting invalid DoM striping should fail"
22613
22614 test_271a() {
22615         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22616                 skip "Need MDS version at least 2.10.55"
22617
22618         local dom=$DIR/$tdir/dom
22619
22620         mkdir -p $DIR/$tdir
22621
22622         $LFS setstripe -E 1024K -L mdt $dom
22623
22624         lctl set_param -n mdc.*.stats=clear
22625         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22626         cat $dom > /dev/null
22627         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22628         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22629         ls $dom
22630         rm -f $dom
22631 }
22632 run_test 271a "DoM: data is cached for read after write"
22633
22634 test_271b() {
22635         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22636                 skip "Need MDS version at least 2.10.55"
22637
22638         local dom=$DIR/$tdir/dom
22639
22640         mkdir -p $DIR/$tdir
22641
22642         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22643
22644         lctl set_param -n mdc.*.stats=clear
22645         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22646         cancel_lru_locks mdc
22647         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22648         # second stat to check size is cached on client
22649         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22650         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22651         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22652         rm -f $dom
22653 }
22654 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22655
22656 test_271ba() {
22657         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22658                 skip "Need MDS version at least 2.10.55"
22659
22660         local dom=$DIR/$tdir/dom
22661
22662         mkdir -p $DIR/$tdir
22663
22664         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22665
22666         lctl set_param -n mdc.*.stats=clear
22667         lctl set_param -n osc.*.stats=clear
22668         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22669         cancel_lru_locks mdc
22670         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22671         # second stat to check size is cached on client
22672         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22673         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22674         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22675         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22676         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22677         rm -f $dom
22678 }
22679 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22680
22681
22682 get_mdc_stats() {
22683         local mdtidx=$1
22684         local param=$2
22685         local mdt=MDT$(printf %04x $mdtidx)
22686
22687         if [ -z $param ]; then
22688                 lctl get_param -n mdc.*$mdt*.stats
22689         else
22690                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22691         fi
22692 }
22693
22694 test_271c() {
22695         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22696                 skip "Need MDS version at least 2.10.55"
22697
22698         local dom=$DIR/$tdir/dom
22699
22700         mkdir -p $DIR/$tdir
22701
22702         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22703
22704         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22705         local facet=mds$((mdtidx + 1))
22706
22707         cancel_lru_locks mdc
22708         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22709         createmany -o $dom 1000
22710         lctl set_param -n mdc.*.stats=clear
22711         smalliomany -w $dom 1000 200
22712         get_mdc_stats $mdtidx
22713         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22714         # Each file has 1 open, 1 IO enqueues, total 2000
22715         # but now we have also +1 getxattr for security.capability, total 3000
22716         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22717         unlinkmany $dom 1000
22718
22719         cancel_lru_locks mdc
22720         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22721         createmany -o $dom 1000
22722         lctl set_param -n mdc.*.stats=clear
22723         smalliomany -w $dom 1000 200
22724         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22725         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22726         # for OPEN and IO lock.
22727         [ $((enq - enq_2)) -ge 1000 ] ||
22728                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22729         unlinkmany $dom 1000
22730         return 0
22731 }
22732 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22733
22734 cleanup_271def_tests() {
22735         trap 0
22736         rm -f $1
22737 }
22738
22739 test_271d() {
22740         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22741                 skip "Need MDS version at least 2.10.57"
22742
22743         local dom=$DIR/$tdir/dom
22744         local tmp=$TMP/$tfile
22745         trap "cleanup_271def_tests $tmp" EXIT
22746
22747         mkdir -p $DIR/$tdir
22748
22749         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22750
22751         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22752
22753         cancel_lru_locks mdc
22754         dd if=/dev/urandom of=$tmp bs=1000 count=1
22755         dd if=$tmp of=$dom bs=1000 count=1
22756         cancel_lru_locks mdc
22757
22758         cat /etc/hosts >> $tmp
22759         lctl set_param -n mdc.*.stats=clear
22760
22761         # append data to the same file it should update local page
22762         echo "Append to the same page"
22763         cat /etc/hosts >> $dom
22764         local num=$(get_mdc_stats $mdtidx ost_read)
22765         local ra=$(get_mdc_stats $mdtidx req_active)
22766         local rw=$(get_mdc_stats $mdtidx req_waittime)
22767
22768         [ -z $num ] || error "$num READ RPC occured"
22769         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22770         echo "... DONE"
22771
22772         # compare content
22773         cmp $tmp $dom || error "file miscompare"
22774
22775         cancel_lru_locks mdc
22776         lctl set_param -n mdc.*.stats=clear
22777
22778         echo "Open and read file"
22779         cat $dom > /dev/null
22780         local num=$(get_mdc_stats $mdtidx ost_read)
22781         local ra=$(get_mdc_stats $mdtidx req_active)
22782         local rw=$(get_mdc_stats $mdtidx req_waittime)
22783
22784         [ -z $num ] || error "$num READ RPC occured"
22785         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22786         echo "... DONE"
22787
22788         # compare content
22789         cmp $tmp $dom || error "file miscompare"
22790
22791         return 0
22792 }
22793 run_test 271d "DoM: read on open (1K file in reply buffer)"
22794
22795 test_271f() {
22796         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22797                 skip "Need MDS version at least 2.10.57"
22798
22799         local dom=$DIR/$tdir/dom
22800         local tmp=$TMP/$tfile
22801         trap "cleanup_271def_tests $tmp" EXIT
22802
22803         mkdir -p $DIR/$tdir
22804
22805         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22806
22807         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22808
22809         cancel_lru_locks mdc
22810         dd if=/dev/urandom of=$tmp bs=265000 count=1
22811         dd if=$tmp of=$dom bs=265000 count=1
22812         cancel_lru_locks mdc
22813         cat /etc/hosts >> $tmp
22814         lctl set_param -n mdc.*.stats=clear
22815
22816         echo "Append to the same page"
22817         cat /etc/hosts >> $dom
22818         local num=$(get_mdc_stats $mdtidx ost_read)
22819         local ra=$(get_mdc_stats $mdtidx req_active)
22820         local rw=$(get_mdc_stats $mdtidx req_waittime)
22821
22822         [ -z $num ] || error "$num READ RPC occured"
22823         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22824         echo "... DONE"
22825
22826         # compare content
22827         cmp $tmp $dom || error "file miscompare"
22828
22829         cancel_lru_locks mdc
22830         lctl set_param -n mdc.*.stats=clear
22831
22832         echo "Open and read file"
22833         cat $dom > /dev/null
22834         local num=$(get_mdc_stats $mdtidx ost_read)
22835         local ra=$(get_mdc_stats $mdtidx req_active)
22836         local rw=$(get_mdc_stats $mdtidx req_waittime)
22837
22838         [ -z $num ] && num=0
22839         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22840         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22841         echo "... DONE"
22842
22843         # compare content
22844         cmp $tmp $dom || error "file miscompare"
22845
22846         return 0
22847 }
22848 run_test 271f "DoM: read on open (200K file and read tail)"
22849
22850 test_271g() {
22851         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22852                 skip "Skipping due to old client or server version"
22853
22854         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22855         # to get layout
22856         $CHECKSTAT -t file $DIR1/$tfile
22857
22858         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22859         MULTIOP_PID=$!
22860         sleep 1
22861         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22862         $LCTL set_param fail_loc=0x80000314
22863         rm $DIR1/$tfile || error "Unlink fails"
22864         RC=$?
22865         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22866         [ $RC -eq 0 ] || error "Failed write to stale object"
22867 }
22868 run_test 271g "Discard DoM data vs client flush race"
22869
22870 test_272a() {
22871         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22872                 skip "Need MDS version at least 2.11.50"
22873
22874         local dom=$DIR/$tdir/dom
22875         mkdir -p $DIR/$tdir
22876
22877         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22878         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22879                 error "failed to write data into $dom"
22880         local old_md5=$(md5sum $dom)
22881
22882         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22883                 error "failed to migrate to the same DoM component"
22884
22885         local new_md5=$(md5sum $dom)
22886
22887         [ "$old_md5" == "$new_md5" ] ||
22888                 error "md5sum differ: $old_md5, $new_md5"
22889
22890         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22891                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22892 }
22893 run_test 272a "DoM migration: new layout with the same DOM component"
22894
22895 test_272b() {
22896         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22897                 skip "Need MDS version at least 2.11.50"
22898
22899         local dom=$DIR/$tdir/dom
22900         mkdir -p $DIR/$tdir
22901         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22902
22903         local mdtidx=$($LFS getstripe -m $dom)
22904         local mdtname=MDT$(printf %04x $mdtidx)
22905         local facet=mds$((mdtidx + 1))
22906
22907         local mdtfree1=$(do_facet $facet \
22908                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22909         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22910                 error "failed to write data into $dom"
22911         local old_md5=$(md5sum $dom)
22912         cancel_lru_locks mdc
22913         local mdtfree1=$(do_facet $facet \
22914                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22915
22916         $LFS migrate -c2 $dom ||
22917                 error "failed to migrate to the new composite layout"
22918         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22919                 error "MDT stripe was not removed"
22920
22921         cancel_lru_locks mdc
22922         local new_md5=$(md5sum $dom)
22923         [ "$old_md5" == "$new_md5" ] ||
22924                 error "$old_md5 != $new_md5"
22925
22926         # Skip free space checks with ZFS
22927         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22928                 local mdtfree2=$(do_facet $facet \
22929                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22930                 [ $mdtfree2 -gt $mdtfree1 ] ||
22931                         error "MDT space is not freed after migration"
22932         fi
22933         return 0
22934 }
22935 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22936
22937 test_272c() {
22938         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22939                 skip "Need MDS version at least 2.11.50"
22940
22941         local dom=$DIR/$tdir/$tfile
22942         mkdir -p $DIR/$tdir
22943         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22944
22945         local mdtidx=$($LFS getstripe -m $dom)
22946         local mdtname=MDT$(printf %04x $mdtidx)
22947         local facet=mds$((mdtidx + 1))
22948
22949         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22950                 error "failed to write data into $dom"
22951         local old_md5=$(md5sum $dom)
22952         cancel_lru_locks mdc
22953         local mdtfree1=$(do_facet $facet \
22954                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22955
22956         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22957                 error "failed to migrate to the new composite layout"
22958         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22959                 error "MDT stripe was not removed"
22960
22961         cancel_lru_locks mdc
22962         local new_md5=$(md5sum $dom)
22963         [ "$old_md5" == "$new_md5" ] ||
22964                 error "$old_md5 != $new_md5"
22965
22966         # Skip free space checks with ZFS
22967         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22968                 local mdtfree2=$(do_facet $facet \
22969                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22970                 [ $mdtfree2 -gt $mdtfree1 ] ||
22971                         error "MDS space is not freed after migration"
22972         fi
22973         return 0
22974 }
22975 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22976
22977 test_272d() {
22978         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22979                 skip "Need MDS version at least 2.12.55"
22980
22981         local dom=$DIR/$tdir/$tfile
22982         mkdir -p $DIR/$tdir
22983         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22984
22985         local mdtidx=$($LFS getstripe -m $dom)
22986         local mdtname=MDT$(printf %04x $mdtidx)
22987         local facet=mds$((mdtidx + 1))
22988
22989         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22990                 error "failed to write data into $dom"
22991         local old_md5=$(md5sum $dom)
22992         cancel_lru_locks mdc
22993         local mdtfree1=$(do_facet $facet \
22994                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22995
22996         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22997                 error "failed mirroring to the new composite layout"
22998         $LFS mirror resync $dom ||
22999                 error "failed mirror resync"
23000         $LFS mirror split --mirror-id 1 -d $dom ||
23001                 error "failed mirror split"
23002
23003         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23004                 error "MDT stripe was not removed"
23005
23006         cancel_lru_locks mdc
23007         local new_md5=$(md5sum $dom)
23008         [ "$old_md5" == "$new_md5" ] ||
23009                 error "$old_md5 != $new_md5"
23010
23011         # Skip free space checks with ZFS
23012         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23013                 local mdtfree2=$(do_facet $facet \
23014                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23015                 [ $mdtfree2 -gt $mdtfree1 ] ||
23016                         error "MDS space is not freed after DOM mirror deletion"
23017         fi
23018         return 0
23019 }
23020 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23021
23022 test_272e() {
23023         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23024                 skip "Need MDS version at least 2.12.55"
23025
23026         local dom=$DIR/$tdir/$tfile
23027         mkdir -p $DIR/$tdir
23028         $LFS setstripe -c 2 $dom
23029
23030         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23031                 error "failed to write data into $dom"
23032         local old_md5=$(md5sum $dom)
23033         cancel_lru_locks
23034
23035         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23036                 error "failed mirroring to the DOM layout"
23037         $LFS mirror resync $dom ||
23038                 error "failed mirror resync"
23039         $LFS mirror split --mirror-id 1 -d $dom ||
23040                 error "failed mirror split"
23041
23042         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23043                 error "MDT stripe wasn't set"
23044
23045         cancel_lru_locks
23046         local new_md5=$(md5sum $dom)
23047         [ "$old_md5" == "$new_md5" ] ||
23048                 error "$old_md5 != $new_md5"
23049
23050         return 0
23051 }
23052 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23053
23054 test_272f() {
23055         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23056                 skip "Need MDS version at least 2.12.55"
23057
23058         local dom=$DIR/$tdir/$tfile
23059         mkdir -p $DIR/$tdir
23060         $LFS setstripe -c 2 $dom
23061
23062         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23063                 error "failed to write data into $dom"
23064         local old_md5=$(md5sum $dom)
23065         cancel_lru_locks
23066
23067         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23068                 error "failed migrating to the DOM file"
23069
23070         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23071                 error "MDT stripe wasn't set"
23072
23073         cancel_lru_locks
23074         local new_md5=$(md5sum $dom)
23075         [ "$old_md5" != "$new_md5" ] &&
23076                 error "$old_md5 != $new_md5"
23077
23078         return 0
23079 }
23080 run_test 272f "DoM migration: OST-striped file to DOM file"
23081
23082 test_273a() {
23083         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23084                 skip "Need MDS version at least 2.11.50"
23085
23086         # Layout swap cannot be done if either file has DOM component,
23087         # this will never be supported, migration should be used instead
23088
23089         local dom=$DIR/$tdir/$tfile
23090         mkdir -p $DIR/$tdir
23091
23092         $LFS setstripe -c2 ${dom}_plain
23093         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23094         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23095                 error "can swap layout with DoM component"
23096         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23097                 error "can swap layout with DoM component"
23098
23099         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23100         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23101                 error "can swap layout with DoM component"
23102         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23103                 error "can swap layout with DoM component"
23104         return 0
23105 }
23106 run_test 273a "DoM: layout swapping should fail with DOM"
23107
23108 test_273b() {
23109         mkdir -p $DIR/$tdir
23110         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23111
23112 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23113         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23114
23115         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23116 }
23117 run_test 273b "DoM: race writeback and object destroy"
23118
23119 test_275() {
23120         remote_ost_nodsh && skip "remote OST with nodsh"
23121         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23122                 skip "Need OST version >= 2.10.57"
23123
23124         local file=$DIR/$tfile
23125         local oss
23126
23127         oss=$(comma_list $(osts_nodes))
23128
23129         dd if=/dev/urandom of=$file bs=1M count=2 ||
23130                 error "failed to create a file"
23131         cancel_lru_locks osc
23132
23133         #lock 1
23134         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23135                 error "failed to read a file"
23136
23137 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23138         $LCTL set_param fail_loc=0x8000031f
23139
23140         cancel_lru_locks osc &
23141         sleep 1
23142
23143 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23144         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23145         #IO takes another lock, but matches the PENDING one
23146         #and places it to the IO RPC
23147         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23148                 error "failed to read a file with PENDING lock"
23149 }
23150 run_test 275 "Read on a canceled duplicate lock"
23151
23152 test_276() {
23153         remote_ost_nodsh && skip "remote OST with nodsh"
23154         local pid
23155
23156         do_facet ost1 "(while true; do \
23157                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23158                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23159         pid=$!
23160
23161         for LOOP in $(seq 20); do
23162                 stop ost1
23163                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23164         done
23165         kill -9 $pid
23166         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23167                 rm $TMP/sanity_276_pid"
23168 }
23169 run_test 276 "Race between mount and obd_statfs"
23170
23171 test_277() {
23172         $LCTL set_param ldlm.namespaces.*.lru_size=0
23173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23174         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23175                         grep ^used_mb | awk '{print $2}')
23176         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23177         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23178                 oflag=direct conv=notrunc
23179         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23180                         grep ^used_mb | awk '{print $2}')
23181         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23182 }
23183 run_test 277 "Direct IO shall drop page cache"
23184
23185 test_278() {
23186         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23187         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23188         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23189                 skip "needs the same host for mdt1 mdt2" && return
23190
23191         local pid1
23192         local pid2
23193
23194 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23195         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23196         stop mds2 &
23197         pid2=$!
23198
23199         stop mds1
23200
23201         echo "Starting MDTs"
23202         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23203         wait $pid2
23204 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23205 #will return NULL
23206         do_facet mds2 $LCTL set_param fail_loc=0
23207
23208         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23209         wait_recovery_complete mds2
23210 }
23211 run_test 278 "Race starting MDS between MDTs stop/start"
23212
23213 test_280() {
23214         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23215                 skip "Need MGS version at least 2.13.52"
23216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23217         combined_mgs_mds || skip "needs combined MGS/MDT"
23218
23219         umount_client $MOUNT
23220 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23221         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23222
23223         mount_client $MOUNT &
23224         sleep 1
23225         stop mgs || error "stop mgs failed"
23226         #for a race mgs would crash
23227         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23228         # make sure we unmount client before remounting
23229         wait
23230         umount_client $MOUNT
23231         mount_client $MOUNT || error "mount client failed"
23232 }
23233 run_test 280 "Race between MGS umount and client llog processing"
23234
23235 cleanup_test_300() {
23236         trap 0
23237         umask $SAVE_UMASK
23238 }
23239 test_striped_dir() {
23240         local mdt_index=$1
23241         local stripe_count
23242         local stripe_index
23243
23244         mkdir -p $DIR/$tdir
23245
23246         SAVE_UMASK=$(umask)
23247         trap cleanup_test_300 RETURN EXIT
23248
23249         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23250                                                 $DIR/$tdir/striped_dir ||
23251                 error "set striped dir error"
23252
23253         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23254         [ "$mode" = "755" ] || error "expect 755 got $mode"
23255
23256         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23257                 error "getdirstripe failed"
23258         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23259         if [ "$stripe_count" != "2" ]; then
23260                 error "1:stripe_count is $stripe_count, expect 2"
23261         fi
23262         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23263         if [ "$stripe_count" != "2" ]; then
23264                 error "2:stripe_count is $stripe_count, expect 2"
23265         fi
23266
23267         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23268         if [ "$stripe_index" != "$mdt_index" ]; then
23269                 error "stripe_index is $stripe_index, expect $mdt_index"
23270         fi
23271
23272         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23273                 error "nlink error after create striped dir"
23274
23275         mkdir $DIR/$tdir/striped_dir/a
23276         mkdir $DIR/$tdir/striped_dir/b
23277
23278         stat $DIR/$tdir/striped_dir/a ||
23279                 error "create dir under striped dir failed"
23280         stat $DIR/$tdir/striped_dir/b ||
23281                 error "create dir under striped dir failed"
23282
23283         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23284                 error "nlink error after mkdir"
23285
23286         rmdir $DIR/$tdir/striped_dir/a
23287         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23288                 error "nlink error after rmdir"
23289
23290         rmdir $DIR/$tdir/striped_dir/b
23291         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23292                 error "nlink error after rmdir"
23293
23294         chattr +i $DIR/$tdir/striped_dir
23295         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23296                 error "immutable flags not working under striped dir!"
23297         chattr -i $DIR/$tdir/striped_dir
23298
23299         rmdir $DIR/$tdir/striped_dir ||
23300                 error "rmdir striped dir error"
23301
23302         cleanup_test_300
23303
23304         true
23305 }
23306
23307 test_300a() {
23308         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23309                 skip "skipped for lustre < 2.7.0"
23310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23311         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23312
23313         test_striped_dir 0 || error "failed on striped dir on MDT0"
23314         test_striped_dir 1 || error "failed on striped dir on MDT0"
23315 }
23316 run_test 300a "basic striped dir sanity test"
23317
23318 test_300b() {
23319         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23320                 skip "skipped for lustre < 2.7.0"
23321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23322         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23323
23324         local i
23325         local mtime1
23326         local mtime2
23327         local mtime3
23328
23329         test_mkdir $DIR/$tdir || error "mkdir fail"
23330         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23331                 error "set striped dir error"
23332         for i in {0..9}; do
23333                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23334                 sleep 1
23335                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23336                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23337                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23338                 sleep 1
23339                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23340                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23341                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23342         done
23343         true
23344 }
23345 run_test 300b "check ctime/mtime for striped dir"
23346
23347 test_300c() {
23348         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23349                 skip "skipped for lustre < 2.7.0"
23350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23352
23353         local file_count
23354
23355         mkdir_on_mdt0 $DIR/$tdir
23356         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23357                 error "set striped dir error"
23358
23359         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23360                 error "chown striped dir failed"
23361
23362         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23363                 error "create 5k files failed"
23364
23365         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23366
23367         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23368
23369         rm -rf $DIR/$tdir
23370 }
23371 run_test 300c "chown && check ls under striped directory"
23372
23373 test_300d() {
23374         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23375                 skip "skipped for lustre < 2.7.0"
23376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23377         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23378
23379         local stripe_count
23380         local file
23381
23382         mkdir -p $DIR/$tdir
23383         $LFS setstripe -c 2 $DIR/$tdir
23384
23385         #local striped directory
23386         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23387                 error "set striped dir error"
23388         #look at the directories for debug purposes
23389         ls -l $DIR/$tdir
23390         $LFS getdirstripe $DIR/$tdir
23391         ls -l $DIR/$tdir/striped_dir
23392         $LFS getdirstripe $DIR/$tdir/striped_dir
23393         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23394                 error "create 10 files failed"
23395
23396         #remote striped directory
23397         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23398                 error "set striped dir error"
23399         #look at the directories for debug purposes
23400         ls -l $DIR/$tdir
23401         $LFS getdirstripe $DIR/$tdir
23402         ls -l $DIR/$tdir/remote_striped_dir
23403         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23404         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23405                 error "create 10 files failed"
23406
23407         for file in $(find $DIR/$tdir); do
23408                 stripe_count=$($LFS getstripe -c $file)
23409                 [ $stripe_count -eq 2 ] ||
23410                         error "wrong stripe $stripe_count for $file"
23411         done
23412
23413         rm -rf $DIR/$tdir
23414 }
23415 run_test 300d "check default stripe under striped directory"
23416
23417 test_300e() {
23418         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23419                 skip "Need MDS version at least 2.7.55"
23420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23422
23423         local stripe_count
23424         local file
23425
23426         mkdir -p $DIR/$tdir
23427
23428         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23429                 error "set striped dir error"
23430
23431         touch $DIR/$tdir/striped_dir/a
23432         touch $DIR/$tdir/striped_dir/b
23433         touch $DIR/$tdir/striped_dir/c
23434
23435         mkdir $DIR/$tdir/striped_dir/dir_a
23436         mkdir $DIR/$tdir/striped_dir/dir_b
23437         mkdir $DIR/$tdir/striped_dir/dir_c
23438
23439         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23440                 error "set striped adir under striped dir error"
23441
23442         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23443                 error "set striped bdir under striped dir error"
23444
23445         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23446                 error "set striped cdir under striped dir error"
23447
23448         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23449                 error "rename dir under striped dir fails"
23450
23451         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23452                 error "rename dir under different stripes fails"
23453
23454         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23455                 error "rename file under striped dir should succeed"
23456
23457         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23458                 error "rename dir under striped dir should succeed"
23459
23460         rm -rf $DIR/$tdir
23461 }
23462 run_test 300e "check rename under striped directory"
23463
23464 test_300f() {
23465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23466         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23467         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23468                 skip "Need MDS version at least 2.7.55"
23469
23470         local stripe_count
23471         local file
23472
23473         rm -rf $DIR/$tdir
23474         mkdir -p $DIR/$tdir
23475
23476         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23477                 error "set striped dir error"
23478
23479         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23480                 error "set striped dir error"
23481
23482         touch $DIR/$tdir/striped_dir/a
23483         mkdir $DIR/$tdir/striped_dir/dir_a
23484         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23485                 error "create striped dir under striped dir fails"
23486
23487         touch $DIR/$tdir/striped_dir1/b
23488         mkdir $DIR/$tdir/striped_dir1/dir_b
23489         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23490                 error "create striped dir under striped dir fails"
23491
23492         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23493                 error "rename dir under different striped dir should fail"
23494
23495         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23496                 error "rename striped dir under diff striped dir should fail"
23497
23498         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23499                 error "rename file under diff striped dirs fails"
23500
23501         rm -rf $DIR/$tdir
23502 }
23503 run_test 300f "check rename cross striped directory"
23504
23505 test_300_check_default_striped_dir()
23506 {
23507         local dirname=$1
23508         local default_count=$2
23509         local default_index=$3
23510         local stripe_count
23511         local stripe_index
23512         local dir_stripe_index
23513         local dir
23514
23515         echo "checking $dirname $default_count $default_index"
23516         $LFS setdirstripe -D -c $default_count -i $default_index \
23517                                 -H all_char $DIR/$tdir/$dirname ||
23518                 error "set default stripe on striped dir error"
23519         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23520         [ $stripe_count -eq $default_count ] ||
23521                 error "expect $default_count get $stripe_count for $dirname"
23522
23523         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23524         [ $stripe_index -eq $default_index ] ||
23525                 error "expect $default_index get $stripe_index for $dirname"
23526
23527         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23528                                                 error "create dirs failed"
23529
23530         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23531         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23532         for dir in $(find $DIR/$tdir/$dirname/*); do
23533                 stripe_count=$($LFS getdirstripe -c $dir)
23534                 (( $stripe_count == $default_count )) ||
23535                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23536                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23537                 error "stripe count $default_count != $stripe_count for $dir"
23538
23539                 stripe_index=$($LFS getdirstripe -i $dir)
23540                 [ $default_index -eq -1 ] ||
23541                         [ $stripe_index -eq $default_index ] ||
23542                         error "$stripe_index != $default_index for $dir"
23543
23544                 #check default stripe
23545                 stripe_count=$($LFS getdirstripe -D -c $dir)
23546                 [ $stripe_count -eq $default_count ] ||
23547                 error "default count $default_count != $stripe_count for $dir"
23548
23549                 stripe_index=$($LFS getdirstripe -D -i $dir)
23550                 [ $stripe_index -eq $default_index ] ||
23551                 error "default index $default_index != $stripe_index for $dir"
23552         done
23553         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23554 }
23555
23556 test_300g() {
23557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23558         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23559                 skip "Need MDS version at least 2.7.55"
23560
23561         local dir
23562         local stripe_count
23563         local stripe_index
23564
23565         mkdir_on_mdt0 $DIR/$tdir
23566         mkdir $DIR/$tdir/normal_dir
23567
23568         #Checking when client cache stripe index
23569         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23570         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23571                 error "create striped_dir failed"
23572
23573         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23574                 error "create dir0 fails"
23575         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23576         [ $stripe_index -eq 0 ] ||
23577                 error "dir0 expect index 0 got $stripe_index"
23578
23579         mkdir $DIR/$tdir/striped_dir/dir1 ||
23580                 error "create dir1 fails"
23581         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23582         [ $stripe_index -eq 1 ] ||
23583                 error "dir1 expect index 1 got $stripe_index"
23584
23585         #check default stripe count/stripe index
23586         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23587         test_300_check_default_striped_dir normal_dir 1 0
23588         test_300_check_default_striped_dir normal_dir -1 1
23589         test_300_check_default_striped_dir normal_dir 2 -1
23590
23591         #delete default stripe information
23592         echo "delete default stripeEA"
23593         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23594                 error "set default stripe on striped dir error"
23595
23596         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23597         for dir in $(find $DIR/$tdir/normal_dir/*); do
23598                 stripe_count=$($LFS getdirstripe -c $dir)
23599                 [ $stripe_count -eq 0 ] ||
23600                         error "expect 1 get $stripe_count for $dir"
23601         done
23602 }
23603 run_test 300g "check default striped directory for normal directory"
23604
23605 test_300h() {
23606         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23607         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23608                 skip "Need MDS version at least 2.7.55"
23609
23610         local dir
23611         local stripe_count
23612
23613         mkdir $DIR/$tdir
23614         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23615                 error "set striped dir error"
23616
23617         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23618         test_300_check_default_striped_dir striped_dir 1 0
23619         test_300_check_default_striped_dir striped_dir -1 1
23620         test_300_check_default_striped_dir striped_dir 2 -1
23621
23622         #delete default stripe information
23623         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23624                 error "set default stripe on striped dir error"
23625
23626         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23627         for dir in $(find $DIR/$tdir/striped_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 300h "check default striped directory for striped directory"
23634
23635 test_300i() {
23636         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23637         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23638         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23639                 skip "Need MDS version at least 2.7.55"
23640
23641         local stripe_count
23642         local file
23643
23644         mkdir $DIR/$tdir
23645
23646         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23647                 error "set striped dir error"
23648
23649         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23650                 error "create files under striped dir failed"
23651
23652         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23653                 error "set striped hashdir error"
23654
23655         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23656                 error "create dir0 under hash dir failed"
23657         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23658                 error "create dir1 under hash dir failed"
23659         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23660                 error "create dir2 under hash dir failed"
23661
23662         # unfortunately, we need to umount to clear dir layout cache for now
23663         # once we fully implement dir layout, we can drop this
23664         umount_client $MOUNT || error "umount failed"
23665         mount_client $MOUNT || error "mount failed"
23666
23667         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23668         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23669         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23670
23671         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23672                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23673                         error "create crush2 dir $tdir/hashdir/d3 failed"
23674                 $LFS find -H crush2 $DIR/$tdir/hashdir
23675                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23676                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23677
23678                 # mkdir with an invalid hash type (hash=fail_val) from client
23679                 # should be replaced on MDS with a valid (default) hash type
23680                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23681                 $LCTL set_param fail_loc=0x1901 fail_val=99
23682                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23683
23684                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23685                 local expect=$(do_facet mds1 \
23686                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23687                 [[ $hash == $expect ]] ||
23688                         error "d99 hash '$hash' != expected hash '$expect'"
23689         fi
23690
23691         #set the stripe to be unknown hash type on read
23692         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23693         $LCTL set_param fail_loc=0x1901 fail_val=99
23694         for ((i = 0; i < 10; i++)); do
23695                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23696                         error "stat f-$i failed"
23697                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23698         done
23699
23700         touch $DIR/$tdir/striped_dir/f0 &&
23701                 error "create under striped dir with unknown hash should fail"
23702
23703         $LCTL set_param fail_loc=0
23704
23705         umount_client $MOUNT || error "umount failed"
23706         mount_client $MOUNT || error "mount failed"
23707
23708         return 0
23709 }
23710 run_test 300i "client handle unknown hash type striped directory"
23711
23712 test_300j() {
23713         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23715         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23716                 skip "Need MDS version at least 2.7.55"
23717
23718         local stripe_count
23719         local file
23720
23721         mkdir $DIR/$tdir
23722
23723         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23724         $LCTL set_param fail_loc=0x1702
23725         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23726                 error "set striped dir error"
23727
23728         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23729                 error "create files under striped dir failed"
23730
23731         $LCTL set_param fail_loc=0
23732
23733         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23734
23735         return 0
23736 }
23737 run_test 300j "test large update record"
23738
23739 test_300k() {
23740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23741         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23742         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23743                 skip "Need MDS version at least 2.7.55"
23744
23745         # this test needs a huge transaction
23746         local kb
23747         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23748              osd*.$FSNAME-MDT0000.kbytestotal")
23749         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23750
23751         local stripe_count
23752         local file
23753
23754         mkdir $DIR/$tdir
23755
23756         #define OBD_FAIL_LARGE_STRIPE   0x1703
23757         $LCTL set_param fail_loc=0x1703
23758         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23759                 error "set striped dir error"
23760         $LCTL set_param fail_loc=0
23761
23762         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23763                 error "getstripeddir fails"
23764         rm -rf $DIR/$tdir/striped_dir ||
23765                 error "unlink striped dir fails"
23766
23767         return 0
23768 }
23769 run_test 300k "test large striped directory"
23770
23771 test_300l() {
23772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23773         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23774         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23775                 skip "Need MDS version at least 2.7.55"
23776
23777         local stripe_index
23778
23779         test_mkdir -p $DIR/$tdir/striped_dir
23780         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23781                         error "chown $RUNAS_ID failed"
23782         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23783                 error "set default striped dir failed"
23784
23785         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23786         $LCTL set_param fail_loc=0x80000158
23787         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23788
23789         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23790         [ $stripe_index -eq 1 ] ||
23791                 error "expect 1 get $stripe_index for $dir"
23792 }
23793 run_test 300l "non-root user to create dir under striped dir with stale layout"
23794
23795 test_300m() {
23796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23797         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23798         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23799                 skip "Need MDS version at least 2.7.55"
23800
23801         mkdir -p $DIR/$tdir/striped_dir
23802         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23803                 error "set default stripes dir error"
23804
23805         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23806
23807         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23808         [ $stripe_count -eq 0 ] ||
23809                         error "expect 0 get $stripe_count for a"
23810
23811         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23812                 error "set default stripes dir error"
23813
23814         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23815
23816         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23817         [ $stripe_count -eq 0 ] ||
23818                         error "expect 0 get $stripe_count for b"
23819
23820         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23821                 error "set default stripes dir error"
23822
23823         mkdir $DIR/$tdir/striped_dir/c &&
23824                 error "default stripe_index is invalid, mkdir c should fails"
23825
23826         rm -rf $DIR/$tdir || error "rmdir fails"
23827 }
23828 run_test 300m "setstriped directory on single MDT FS"
23829
23830 cleanup_300n() {
23831         local list=$(comma_list $(mdts_nodes))
23832
23833         trap 0
23834         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23835 }
23836
23837 test_300n() {
23838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23839         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23840         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23841                 skip "Need MDS version at least 2.7.55"
23842         remote_mds_nodsh && skip "remote MDS with nodsh"
23843
23844         local stripe_index
23845         local list=$(comma_list $(mdts_nodes))
23846
23847         trap cleanup_300n RETURN EXIT
23848         mkdir -p $DIR/$tdir
23849         chmod 777 $DIR/$tdir
23850         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23851                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23852                 error "create striped dir succeeds with gid=0"
23853
23854         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23855         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23856                 error "create striped dir fails with gid=-1"
23857
23858         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23859         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23860                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23861                 error "set default striped dir succeeds with gid=0"
23862
23863
23864         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23865         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23866                 error "set default striped dir fails with gid=-1"
23867
23868
23869         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23870         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23871                                         error "create test_dir fails"
23872         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23873                                         error "create test_dir1 fails"
23874         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23875                                         error "create test_dir2 fails"
23876         cleanup_300n
23877 }
23878 run_test 300n "non-root user to create dir under striped dir with default EA"
23879
23880 test_300o() {
23881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23883         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23884                 skip "Need MDS version at least 2.7.55"
23885
23886         local numfree1
23887         local numfree2
23888
23889         mkdir -p $DIR/$tdir
23890
23891         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23892         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23893         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23894                 skip "not enough free inodes $numfree1 $numfree2"
23895         fi
23896
23897         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23898         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23899         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23900                 skip "not enough free space $numfree1 $numfree2"
23901         fi
23902
23903         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23904                 error "setdirstripe fails"
23905
23906         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23907                 error "create dirs fails"
23908
23909         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23910         ls $DIR/$tdir/striped_dir > /dev/null ||
23911                 error "ls striped dir fails"
23912         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23913                 error "unlink big striped dir fails"
23914 }
23915 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23916
23917 test_300p() {
23918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23919         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23920         remote_mds_nodsh && skip "remote MDS with nodsh"
23921
23922         mkdir_on_mdt0 $DIR/$tdir
23923
23924         #define OBD_FAIL_OUT_ENOSPC     0x1704
23925         do_facet mds2 lctl set_param fail_loc=0x80001704
23926         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23927                  && error "create striped directory should fail"
23928
23929         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23930
23931         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23932         true
23933 }
23934 run_test 300p "create striped directory without space"
23935
23936 test_300q() {
23937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23939
23940         local fd=$(free_fd)
23941         local cmd="exec $fd<$tdir"
23942         cd $DIR
23943         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23944         eval $cmd
23945         cmd="exec $fd<&-"
23946         trap "eval $cmd" EXIT
23947         cd $tdir || error "cd $tdir fails"
23948         rmdir  ../$tdir || error "rmdir $tdir fails"
23949         mkdir local_dir && error "create dir succeeds"
23950         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23951         eval $cmd
23952         return 0
23953 }
23954 run_test 300q "create remote directory under orphan directory"
23955
23956 test_300r() {
23957         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23958                 skip "Need MDS version at least 2.7.55" && return
23959         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23960
23961         mkdir $DIR/$tdir
23962
23963         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23964                 error "set striped dir error"
23965
23966         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23967                 error "getstripeddir fails"
23968
23969         local stripe_count
23970         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23971                       awk '/lmv_stripe_count:/ { print $2 }')
23972
23973         [ $MDSCOUNT -ne $stripe_count ] &&
23974                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23975
23976         rm -rf $DIR/$tdir/striped_dir ||
23977                 error "unlink striped dir fails"
23978 }
23979 run_test 300r "test -1 striped directory"
23980
23981 test_300s_helper() {
23982         local count=$1
23983
23984         local stripe_dir=$DIR/$tdir/striped_dir.$count
23985
23986         $LFS mkdir -c $count $stripe_dir ||
23987                 error "lfs mkdir -c error"
23988
23989         $LFS getdirstripe $stripe_dir ||
23990                 error "lfs getdirstripe fails"
23991
23992         local stripe_count
23993         stripe_count=$($LFS getdirstripe $stripe_dir |
23994                       awk '/lmv_stripe_count:/ { print $2 }')
23995
23996         [ $count -ne $stripe_count ] &&
23997                 error_noexit "bad stripe count $stripe_count expected $count"
23998
23999         local dupe_stripes
24000         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24001                 awk '/0x/ {count[$1] += 1}; END {
24002                         for (idx in count) {
24003                                 if (count[idx]>1) {
24004                                         print "index " idx " count " count[idx]
24005                                 }
24006                         }
24007                 }')
24008
24009         if [[ -n "$dupe_stripes" ]] ; then
24010                 lfs getdirstripe $stripe_dir
24011                 error_noexit "Dupe MDT above: $dupe_stripes "
24012         fi
24013
24014         rm -rf $stripe_dir ||
24015                 error_noexit "unlink $stripe_dir fails"
24016 }
24017
24018 test_300s() {
24019         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24020                 skip "Need MDS version at least 2.7.55" && return
24021         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24022
24023         mkdir $DIR/$tdir
24024         for count in $(seq 2 $MDSCOUNT); do
24025                 test_300s_helper $count
24026         done
24027 }
24028 run_test 300s "test lfs mkdir -c without -i"
24029
24030 test_300t() {
24031         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24032                 skip "need MDS 2.14.55 or later"
24033         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24034
24035         local testdir="$DIR/$tdir/striped_dir"
24036         local dir1=$testdir/dir1
24037         local dir2=$testdir/dir2
24038
24039         mkdir -p $testdir
24040
24041         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24042                 error "failed to set default stripe count for $testdir"
24043
24044         mkdir $dir1
24045         local stripe_count=$($LFS getdirstripe -c $dir1)
24046
24047         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24048
24049         local max_count=$((MDSCOUNT - 1))
24050         local mdts=$(comma_list $(mdts_nodes))
24051
24052         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24053         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24054
24055         mkdir $dir2
24056         stripe_count=$($LFS getdirstripe -c $dir2)
24057
24058         (( $stripe_count == $max_count )) || error "wrong stripe count"
24059 }
24060 run_test 300t "test max_mdt_stripecount"
24061
24062 prepare_remote_file() {
24063         mkdir $DIR/$tdir/src_dir ||
24064                 error "create remote source failed"
24065
24066         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24067                  error "cp to remote source failed"
24068         touch $DIR/$tdir/src_dir/a
24069
24070         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24071                 error "create remote target dir failed"
24072
24073         touch $DIR/$tdir/tgt_dir/b
24074
24075         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24076                 error "rename dir cross MDT failed!"
24077
24078         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24079                 error "src_child still exists after rename"
24080
24081         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24082                 error "missing file(a) after rename"
24083
24084         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24085                 error "diff after rename"
24086 }
24087
24088 test_310a() {
24089         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24091
24092         local remote_file=$DIR/$tdir/tgt_dir/b
24093
24094         mkdir -p $DIR/$tdir
24095
24096         prepare_remote_file || error "prepare remote file failed"
24097
24098         #open-unlink file
24099         $OPENUNLINK $remote_file $remote_file ||
24100                 error "openunlink $remote_file failed"
24101         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24102 }
24103 run_test 310a "open unlink remote file"
24104
24105 test_310b() {
24106         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24108
24109         local remote_file=$DIR/$tdir/tgt_dir/b
24110
24111         mkdir -p $DIR/$tdir
24112
24113         prepare_remote_file || error "prepare remote file failed"
24114
24115         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24116         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24117         $CHECKSTAT -t file $remote_file || error "check file failed"
24118 }
24119 run_test 310b "unlink remote file with multiple links while open"
24120
24121 test_310c() {
24122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24123         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24124
24125         local remote_file=$DIR/$tdir/tgt_dir/b
24126
24127         mkdir -p $DIR/$tdir
24128
24129         prepare_remote_file || error "prepare remote file failed"
24130
24131         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24132         multiop_bg_pause $remote_file O_uc ||
24133                         error "mulitop failed for remote file"
24134         MULTIPID=$!
24135         $MULTIOP $DIR/$tfile Ouc
24136         kill -USR1 $MULTIPID
24137         wait $MULTIPID
24138 }
24139 run_test 310c "open-unlink remote file with multiple links"
24140
24141 #LU-4825
24142 test_311() {
24143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24144         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24145         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24146                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24147         remote_mds_nodsh && skip "remote MDS with nodsh"
24148
24149         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24150         local mdts=$(comma_list $(mdts_nodes))
24151
24152         mkdir -p $DIR/$tdir
24153         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24154         createmany -o $DIR/$tdir/$tfile. 1000
24155
24156         # statfs data is not real time, let's just calculate it
24157         old_iused=$((old_iused + 1000))
24158
24159         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24160                         osp.*OST0000*MDT0000.create_count")
24161         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24162                                 osp.*OST0000*MDT0000.max_create_count")
24163         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24164
24165         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24166         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24167         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24168
24169         unlinkmany $DIR/$tdir/$tfile. 1000
24170
24171         do_nodes $mdts "$LCTL set_param -n \
24172                         osp.*OST0000*.max_create_count=$max_count"
24173         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24174                 do_nodes $mdts "$LCTL set_param -n \
24175                                 osp.*OST0000*.create_count=$count"
24176         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24177                         grep "=0" && error "create_count is zero"
24178
24179         local new_iused
24180         for i in $(seq 120); do
24181                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24182                 # system may be too busy to destroy all objs in time, use
24183                 # a somewhat small value to not fail autotest
24184                 [ $((old_iused - new_iused)) -gt 400 ] && break
24185                 sleep 1
24186         done
24187
24188         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24189         [ $((old_iused - new_iused)) -gt 400 ] ||
24190                 error "objs not destroyed after unlink"
24191 }
24192 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24193
24194 zfs_oid_to_objid()
24195 {
24196         local ost=$1
24197         local objid=$2
24198
24199         local vdevdir=$(dirname $(facet_vdevice $ost))
24200         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24201         local zfs_zapid=$(do_facet $ost $cmd |
24202                           grep -w "/O/0/d$((objid%32))" -C 5 |
24203                           awk '/Object/{getline; print $1}')
24204         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24205                           awk "/$objid = /"'{printf $3}')
24206
24207         echo $zfs_objid
24208 }
24209
24210 zfs_object_blksz() {
24211         local ost=$1
24212         local objid=$2
24213
24214         local vdevdir=$(dirname $(facet_vdevice $ost))
24215         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24216         local blksz=$(do_facet $ost $cmd $objid |
24217                       awk '/dblk/{getline; printf $4}')
24218
24219         case "${blksz: -1}" in
24220                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24221                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24222                 *) ;;
24223         esac
24224
24225         echo $blksz
24226 }
24227
24228 test_312() { # LU-4856
24229         remote_ost_nodsh && skip "remote OST with nodsh"
24230         [ "$ost1_FSTYPE" = "zfs" ] ||
24231                 skip_env "the test only applies to zfs"
24232
24233         local max_blksz=$(do_facet ost1 \
24234                           $ZFS get -p recordsize $(facet_device ost1) |
24235                           awk '!/VALUE/{print $3}')
24236
24237         # to make life a little bit easier
24238         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24239         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24240
24241         local tf=$DIR/$tdir/$tfile
24242         touch $tf
24243         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24244
24245         # Get ZFS object id
24246         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24247         # block size change by sequential overwrite
24248         local bs
24249
24250         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24251                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24252
24253                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24254                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24255         done
24256         rm -f $tf
24257
24258         # block size change by sequential append write
24259         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24260         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24261         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24262         local count
24263
24264         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24265                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24266                         oflag=sync conv=notrunc
24267
24268                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24269                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24270                         error "blksz error, actual $blksz, " \
24271                                 "expected: 2 * $count * $PAGE_SIZE"
24272         done
24273         rm -f $tf
24274
24275         # random write
24276         touch $tf
24277         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24278         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24279
24280         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24281         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24282         [ $blksz -eq $PAGE_SIZE ] ||
24283                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24284
24285         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24286         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24287         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24288
24289         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24290         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24291         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24292 }
24293 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24294
24295 test_313() {
24296         remote_ost_nodsh && skip "remote OST with nodsh"
24297
24298         local file=$DIR/$tfile
24299
24300         rm -f $file
24301         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24302
24303         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24304         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24305         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24306                 error "write should failed"
24307         do_facet ost1 "$LCTL set_param fail_loc=0"
24308         rm -f $file
24309 }
24310 run_test 313 "io should fail after last_rcvd update fail"
24311
24312 test_314() {
24313         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24314
24315         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24316         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24317         rm -f $DIR/$tfile
24318         wait_delete_completed
24319         do_facet ost1 "$LCTL set_param fail_loc=0"
24320 }
24321 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24322
24323 test_315() { # LU-618
24324         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24325
24326         local file=$DIR/$tfile
24327         rm -f $file
24328
24329         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24330                 error "multiop file write failed"
24331         $MULTIOP $file oO_RDONLY:r4063232_c &
24332         PID=$!
24333
24334         sleep 2
24335
24336         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24337         kill -USR1 $PID
24338
24339         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24340         rm -f $file
24341 }
24342 run_test 315 "read should be accounted"
24343
24344 test_316() {
24345         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24346         large_xattr_enabled || skip "ea_inode feature disabled"
24347
24348         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24349         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24350         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24351         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24352
24353         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24354 }
24355 run_test 316 "lfs migrate of file with large_xattr enabled"
24356
24357 test_317() {
24358         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24359                 skip "Need MDS version at least 2.11.53"
24360         if [ "$ost1_FSTYPE" == "zfs" ]; then
24361                 skip "LU-10370: no implementation for ZFS"
24362         fi
24363
24364         local trunc_sz
24365         local grant_blk_size
24366
24367         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24368                         awk '/grant_block_size:/ { print $2; exit; }')
24369         #
24370         # Create File of size 5M. Truncate it to below size's and verify
24371         # blocks count.
24372         #
24373         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24374                 error "Create file $DIR/$tfile failed"
24375         stack_trap "rm -f $DIR/$tfile" EXIT
24376
24377         for trunc_sz in 2097152 4097 4000 509 0; do
24378                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24379                         error "truncate $tfile to $trunc_sz failed"
24380                 local sz=$(stat --format=%s $DIR/$tfile)
24381                 local blk=$(stat --format=%b $DIR/$tfile)
24382                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24383                                      grant_blk_size) * 8))
24384
24385                 if [[ $blk -ne $trunc_blk ]]; then
24386                         $(which stat) $DIR/$tfile
24387                         error "Expected Block $trunc_blk got $blk for $tfile"
24388                 fi
24389
24390                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24391                         error "Expected Size $trunc_sz got $sz for $tfile"
24392         done
24393
24394         #
24395         # sparse file test
24396         # Create file with a hole and write actual 65536 bytes which aligned
24397         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24398         #
24399         local bs=65536
24400         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24401                 error "Create file : $DIR/$tfile"
24402
24403         #
24404         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24405         # blocks. The block count must drop to 8.
24406         #
24407         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24408                 ((bs - grant_blk_size) + 1)))
24409         $TRUNCATE $DIR/$tfile $trunc_sz ||
24410                 error "truncate $tfile to $trunc_sz failed"
24411
24412         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24413         sz=$(stat --format=%s $DIR/$tfile)
24414         blk=$(stat --format=%b $DIR/$tfile)
24415
24416         if [[ $blk -ne $trunc_bsz ]]; then
24417                 $(which stat) $DIR/$tfile
24418                 error "Expected Block $trunc_bsz got $blk for $tfile"
24419         fi
24420
24421         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24422                 error "Expected Size $trunc_sz got $sz for $tfile"
24423 }
24424 run_test 317 "Verify blocks get correctly update after truncate"
24425
24426 test_318() {
24427         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24428         local old_max_active=$($LCTL get_param -n \
24429                             ${llite_name}.max_read_ahead_async_active \
24430                             2>/dev/null)
24431
24432         $LCTL set_param llite.*.max_read_ahead_async_active=256
24433         local max_active=$($LCTL get_param -n \
24434                            ${llite_name}.max_read_ahead_async_active \
24435                            2>/dev/null)
24436         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24437
24438         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24439                 error "set max_read_ahead_async_active should succeed"
24440
24441         $LCTL set_param llite.*.max_read_ahead_async_active=512
24442         max_active=$($LCTL get_param -n \
24443                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24444         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24445
24446         # restore @max_active
24447         [ $old_max_active -ne 0 ] && $LCTL set_param \
24448                 llite.*.max_read_ahead_async_active=$old_max_active
24449
24450         local old_threshold=$($LCTL get_param -n \
24451                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24452         local max_per_file_mb=$($LCTL get_param -n \
24453                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24454
24455         local invalid=$(($max_per_file_mb + 1))
24456         $LCTL set_param \
24457                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24458                         && error "set $invalid should fail"
24459
24460         local valid=$(($invalid - 1))
24461         $LCTL set_param \
24462                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24463                         error "set $valid should succeed"
24464         local threshold=$($LCTL get_param -n \
24465                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24466         [ $threshold -eq $valid ] || error \
24467                 "expect threshold $valid got $threshold"
24468         $LCTL set_param \
24469                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24470 }
24471 run_test 318 "Verify async readahead tunables"
24472
24473 test_319() {
24474         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24475
24476         local before=$(date +%s)
24477         local evict
24478         local mdir=$DIR/$tdir
24479         local file=$mdir/xxx
24480
24481         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24482         touch $file
24483
24484 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24485         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24486         $LFS migrate -m1 $mdir &
24487
24488         sleep 1
24489         dd if=$file of=/dev/null
24490         wait
24491         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24492           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24493
24494         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24495 }
24496 run_test 319 "lost lease lock on migrate error"
24497
24498 test_398a() { # LU-4198
24499         local ost1_imp=$(get_osc_import_name client ost1)
24500         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24501                          cut -d'.' -f2)
24502
24503         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24504         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24505
24506         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24507         # request a new lock on client
24508         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24509
24510         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24511         #local lock_count=$($LCTL get_param -n \
24512         #                  ldlm.namespaces.$imp_name.lru_size)
24513         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24514
24515         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24516
24517         # no lock cached, should use lockless DIO and not enqueue new lock
24518         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24519                 conv=notrunc ||
24520                 error "dio write failed"
24521         lock_count=$($LCTL get_param -n \
24522                      ldlm.namespaces.$imp_name.lru_size)
24523         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24524
24525         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24526
24527         # no lock cached, should use locked DIO append
24528         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24529                 conv=notrunc || error "DIO append failed"
24530         lock_count=$($LCTL get_param -n \
24531                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24532         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24533 }
24534 run_test 398a "direct IO should cancel lock otherwise lockless"
24535
24536 test_398b() { # LU-4198
24537         which fio || skip_env "no fio installed"
24538         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24539
24540         local size=48
24541         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24542
24543         local njobs=4
24544         # Single page, multiple pages, stripe size, 4*stripe size
24545         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24546                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24547                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24548                         --numjobs=$njobs --fallocate=none \
24549                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24550                         --filename=$DIR/$tfile &
24551                 bg_pid=$!
24552
24553                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24554                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24555                         --numjobs=$njobs --fallocate=none \
24556                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24557                         --filename=$DIR/$tfile || true
24558                 wait $bg_pid
24559         done
24560
24561         evict=$(do_facet client $LCTL get_param \
24562                 osc.$FSNAME-OST*-osc-*/state |
24563             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24564
24565         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24566                 (do_facet client $LCTL get_param \
24567                         osc.$FSNAME-OST*-osc-*/state;
24568                     error "eviction happened: $evict before:$before")
24569
24570         rm -f $DIR/$tfile
24571 }
24572 run_test 398b "DIO and buffer IO race"
24573
24574 test_398c() { # LU-4198
24575         local ost1_imp=$(get_osc_import_name client ost1)
24576         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24577                          cut -d'.' -f2)
24578
24579         which fio || skip_env "no fio installed"
24580
24581         saved_debug=$($LCTL get_param -n debug)
24582         $LCTL set_param debug=0
24583
24584         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24585         ((size /= 1024)) # by megabytes
24586         ((size /= 2)) # write half of the OST at most
24587         [ $size -gt 40 ] && size=40 #reduce test time anyway
24588
24589         $LFS setstripe -c 1 $DIR/$tfile
24590
24591         # it seems like ldiskfs reserves more space than necessary if the
24592         # writing blocks are not mapped, so it extends the file firstly
24593         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24594         cancel_lru_locks osc
24595
24596         # clear and verify rpc_stats later
24597         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24598
24599         local njobs=4
24600         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24601         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24602                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24603                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24604                 --filename=$DIR/$tfile
24605         [ $? -eq 0 ] || error "fio write error"
24606
24607         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24608                 error "Locks were requested while doing AIO"
24609
24610         # get the percentage of 1-page I/O
24611         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24612                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24613                 awk '{print $7}')
24614         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24615
24616         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24617         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24618                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24619                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24620                 --filename=$DIR/$tfile
24621         [ $? -eq 0 ] || error "fio mixed read write error"
24622
24623         echo "AIO with large block size ${size}M"
24624         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24625                 --numjobs=1 --fallocate=none --ioengine=libaio \
24626                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24627                 --filename=$DIR/$tfile
24628         [ $? -eq 0 ] || error "fio large block size failed"
24629
24630         rm -f $DIR/$tfile
24631         $LCTL set_param debug="$saved_debug"
24632 }
24633 run_test 398c "run fio to test AIO"
24634
24635 test_398d() { #  LU-13846
24636         which aiocp || skip_env "no aiocp installed"
24637         local aio_file=$DIR/$tfile.aio
24638
24639         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24640
24641         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24642         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24643         stack_trap "rm -f $DIR/$tfile $aio_file"
24644
24645         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24646
24647         # make sure we don't crash and fail properly
24648         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24649                 error "aio not aligned with PAGE SIZE should fail"
24650
24651         rm -f $DIR/$tfile $aio_file
24652 }
24653 run_test 398d "run aiocp to verify block size > stripe size"
24654
24655 test_398e() {
24656         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24657         touch $DIR/$tfile.new
24658         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24659 }
24660 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24661
24662 test_398f() { #  LU-14687
24663         which aiocp || skip_env "no aiocp installed"
24664         local aio_file=$DIR/$tfile.aio
24665
24666         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24667
24668         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24669         stack_trap "rm -f $DIR/$tfile $aio_file"
24670
24671         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24672         $LCTL set_param fail_loc=0x1418
24673         # make sure we don't crash and fail properly
24674         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24675                 error "aio with page allocation failure succeeded"
24676         $LCTL set_param fail_loc=0
24677         diff $DIR/$tfile $aio_file
24678         [[ $? != 0 ]] || error "no diff after failed aiocp"
24679 }
24680 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24681
24682 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24683 # stripe and i/o size must be > stripe size
24684 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24685 # single RPC in flight.  This test shows async DIO submission is working by
24686 # showing multiple RPCs in flight.
24687 test_398g() { #  LU-13798
24688         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24689
24690         # We need to do some i/o first to acquire enough grant to put our RPCs
24691         # in flight; otherwise a new connection may not have enough grant
24692         # available
24693         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24694                 error "parallel dio failed"
24695         stack_trap "rm -f $DIR/$tfile"
24696
24697         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24698         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24699         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24700         stack_trap "$LCTL set_param -n $pages_per_rpc"
24701
24702         # Recreate file so it's empty
24703         rm -f $DIR/$tfile
24704         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24705         #Pause rpc completion to guarantee we see multiple rpcs in flight
24706         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24707         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24708         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24709
24710         # Clear rpc stats
24711         $LCTL set_param osc.*.rpc_stats=c
24712
24713         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24714                 error "parallel dio failed"
24715         stack_trap "rm -f $DIR/$tfile"
24716
24717         $LCTL get_param osc.*-OST0000-*.rpc_stats
24718         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24719                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24720                 grep "8:" | awk '{print $8}')
24721         # We look at the "8 rpcs in flight" field, and verify A) it is present
24722         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24723         # as expected for an 8M DIO to a file with 1M stripes.
24724         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24725
24726         # Verify turning off parallel dio works as expected
24727         # Clear rpc stats
24728         $LCTL set_param osc.*.rpc_stats=c
24729         $LCTL set_param llite.*.parallel_dio=0
24730         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24731
24732         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24733                 error "dio with parallel dio disabled failed"
24734
24735         # Ideally, we would see only one RPC in flight here, but there is an
24736         # unavoidable race between i/o completion and RPC in flight counting,
24737         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24738         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24739         # So instead we just verify it's always < 8.
24740         $LCTL get_param osc.*-OST0000-*.rpc_stats
24741         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24742                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24743                 grep '^$' -B1 | grep . | awk '{print $1}')
24744         [ $ret != "8:" ] ||
24745                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24746 }
24747 run_test 398g "verify parallel dio async RPC submission"
24748
24749 test_398h() { #  LU-13798
24750         local dio_file=$DIR/$tfile.dio
24751
24752         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24753
24754         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24755         stack_trap "rm -f $DIR/$tfile $dio_file"
24756
24757         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24758                 error "parallel dio failed"
24759         diff $DIR/$tfile $dio_file
24760         [[ $? == 0 ]] || error "file diff after aiocp"
24761 }
24762 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24763
24764 test_398i() { #  LU-13798
24765         local dio_file=$DIR/$tfile.dio
24766
24767         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24768
24769         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24770         stack_trap "rm -f $DIR/$tfile $dio_file"
24771
24772         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24773         $LCTL set_param fail_loc=0x1418
24774         # make sure we don't crash and fail properly
24775         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24776                 error "parallel dio page allocation failure succeeded"
24777         diff $DIR/$tfile $dio_file
24778         [[ $? != 0 ]] || error "no diff after failed aiocp"
24779 }
24780 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24781
24782 test_398j() { #  LU-13798
24783         # Stripe size > RPC size but less than i/o size tests split across
24784         # stripes and RPCs for individual i/o op
24785         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24786
24787         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24788         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24789         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24790         stack_trap "$LCTL set_param -n $pages_per_rpc"
24791
24792         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24793                 error "parallel dio write failed"
24794         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24795
24796         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24797                 error "parallel dio read failed"
24798         diff $DIR/$tfile $DIR/$tfile.2
24799         [[ $? == 0 ]] || error "file diff after parallel dio read"
24800 }
24801 run_test 398j "test parallel dio where stripe size > rpc_size"
24802
24803 test_398k() { #  LU-13798
24804         wait_delete_completed
24805         wait_mds_ost_sync
24806
24807         # 4 stripe file; we will cause out of space on OST0
24808         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24809
24810         # Fill OST0 (if it's not too large)
24811         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24812                    head -n1)
24813         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24814                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24815         fi
24816         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24817         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24818                 error "dd should fill OST0"
24819         stack_trap "rm -f $DIR/$tfile.1"
24820
24821         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24822         err=$?
24823
24824         ls -la $DIR/$tfile
24825         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24826                 error "file is not 0 bytes in size"
24827
24828         # dd above should not succeed, but don't error until here so we can
24829         # get debug info above
24830         [[ $err != 0 ]] ||
24831                 error "parallel dio write with enospc succeeded"
24832         stack_trap "rm -f $DIR/$tfile"
24833 }
24834 run_test 398k "test enospc on first stripe"
24835
24836 test_398l() { #  LU-13798
24837         wait_delete_completed
24838         wait_mds_ost_sync
24839
24840         # 4 stripe file; we will cause out of space on OST0
24841         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24842         # happens on the second i/o chunk we issue
24843         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24844
24845         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24846         stack_trap "rm -f $DIR/$tfile"
24847
24848         # Fill OST0 (if it's not too large)
24849         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24850                    head -n1)
24851         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24852                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24853         fi
24854         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24855         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24856                 error "dd should fill OST0"
24857         stack_trap "rm -f $DIR/$tfile.1"
24858
24859         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24860         err=$?
24861         stack_trap "rm -f $DIR/$tfile.2"
24862
24863         # Check that short write completed as expected
24864         ls -la $DIR/$tfile.2
24865         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24866                 error "file is not 1M in size"
24867
24868         # dd above should not succeed, but don't error until here so we can
24869         # get debug info above
24870         [[ $err != 0 ]] ||
24871                 error "parallel dio write with enospc succeeded"
24872
24873         # Truncate source file to same length as output file and diff them
24874         $TRUNCATE $DIR/$tfile 1048576
24875         diff $DIR/$tfile $DIR/$tfile.2
24876         [[ $? == 0 ]] || error "data incorrect after short write"
24877 }
24878 run_test 398l "test enospc on intermediate stripe/RPC"
24879
24880 test_398m() { #  LU-13798
24881         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24882
24883         # Set up failure on OST0, the first stripe:
24884         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24885         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24886         # So this fail_val specifies OST0
24887         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24888         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24889
24890         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24891                 error "parallel dio write with failure on first stripe succeeded"
24892         stack_trap "rm -f $DIR/$tfile"
24893         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24894
24895         # Place data in file for read
24896         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24897                 error "parallel dio write failed"
24898
24899         # Fail read on OST0, first stripe
24900         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24901         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24902         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24903                 error "parallel dio read with error on first stripe succeeded"
24904         rm -f $DIR/$tfile.2
24905         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24906
24907         # Switch to testing on OST1, second stripe
24908         # Clear file contents, maintain striping
24909         echo > $DIR/$tfile
24910         # Set up failure on OST1, second stripe:
24911         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24912         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24913
24914         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24915                 error "parallel dio write with failure on first stripe succeeded"
24916         stack_trap "rm -f $DIR/$tfile"
24917         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24918
24919         # Place data in file for read
24920         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24921                 error "parallel dio write failed"
24922
24923         # Fail read on OST1, second stripe
24924         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24925         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24926         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24927                 error "parallel dio read with error on first stripe succeeded"
24928         rm -f $DIR/$tfile.2
24929         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24930 }
24931 run_test 398m "test RPC failures with parallel dio"
24932
24933 # Parallel submission of DIO should not cause problems for append, but it's
24934 # important to verify.
24935 test_398n() { #  LU-13798
24936         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24937
24938         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24939                 error "dd to create source file failed"
24940         stack_trap "rm -f $DIR/$tfile"
24941
24942         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24943                 error "parallel dio write with failure on second stripe succeeded"
24944         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24945         diff $DIR/$tfile $DIR/$tfile.1
24946         [[ $? == 0 ]] || error "data incorrect after append"
24947
24948 }
24949 run_test 398n "test append with parallel DIO"
24950
24951 test_fake_rw() {
24952         local read_write=$1
24953         if [ "$read_write" = "write" ]; then
24954                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24955         elif [ "$read_write" = "read" ]; then
24956                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24957         else
24958                 error "argument error"
24959         fi
24960
24961         # turn off debug for performance testing
24962         local saved_debug=$($LCTL get_param -n debug)
24963         $LCTL set_param debug=0
24964
24965         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24966
24967         # get ost1 size - $FSNAME-OST0000
24968         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24969         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24970         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24971
24972         if [ "$read_write" = "read" ]; then
24973                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24974         fi
24975
24976         local start_time=$(date +%s.%N)
24977         $dd_cmd bs=1M count=$blocks oflag=sync ||
24978                 error "real dd $read_write error"
24979         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24980
24981         if [ "$read_write" = "write" ]; then
24982                 rm -f $DIR/$tfile
24983         fi
24984
24985         # define OBD_FAIL_OST_FAKE_RW           0x238
24986         do_facet ost1 $LCTL set_param fail_loc=0x238
24987
24988         local start_time=$(date +%s.%N)
24989         $dd_cmd bs=1M count=$blocks oflag=sync ||
24990                 error "fake dd $read_write error"
24991         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24992
24993         if [ "$read_write" = "write" ]; then
24994                 # verify file size
24995                 cancel_lru_locks osc
24996                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24997                         error "$tfile size not $blocks MB"
24998         fi
24999         do_facet ost1 $LCTL set_param fail_loc=0
25000
25001         echo "fake $read_write $duration_fake vs. normal $read_write" \
25002                 "$duration in seconds"
25003         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25004                 error_not_in_vm "fake write is slower"
25005
25006         $LCTL set_param -n debug="$saved_debug"
25007         rm -f $DIR/$tfile
25008 }
25009 test_399a() { # LU-7655 for OST fake write
25010         remote_ost_nodsh && skip "remote OST with nodsh"
25011
25012         test_fake_rw write
25013 }
25014 run_test 399a "fake write should not be slower than normal write"
25015
25016 test_399b() { # LU-8726 for OST fake read
25017         remote_ost_nodsh && skip "remote OST with nodsh"
25018         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25019                 skip_env "ldiskfs only test"
25020         fi
25021
25022         test_fake_rw read
25023 }
25024 run_test 399b "fake read should not be slower than normal read"
25025
25026 test_400a() { # LU-1606, was conf-sanity test_74
25027         if ! which $CC > /dev/null 2>&1; then
25028                 skip_env "$CC is not installed"
25029         fi
25030
25031         local extra_flags=''
25032         local out=$TMP/$tfile
25033         local prefix=/usr/include/lustre
25034         local prog
25035
25036         # Oleg removes c files in his test rig so test if any c files exist
25037         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25038                 skip_env "Needed c test files are missing"
25039
25040         if ! [[ -d $prefix ]]; then
25041                 # Assume we're running in tree and fixup the include path.
25042                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25043                 extra_flags+=" -L$LUSTRE/utils/.lib"
25044         fi
25045
25046         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25047                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25048                         error "client api broken"
25049         done
25050         rm -f $out
25051 }
25052 run_test 400a "Lustre client api program can compile and link"
25053
25054 test_400b() { # LU-1606, LU-5011
25055         local header
25056         local out=$TMP/$tfile
25057         local prefix=/usr/include/linux/lustre
25058
25059         # We use a hard coded prefix so that this test will not fail
25060         # when run in tree. There are headers in lustre/include/lustre/
25061         # that are not packaged (like lustre_idl.h) and have more
25062         # complicated include dependencies (like config.h and lnet/types.h).
25063         # Since this test about correct packaging we just skip them when
25064         # they don't exist (see below) rather than try to fixup cppflags.
25065
25066         if ! which $CC > /dev/null 2>&1; then
25067                 skip_env "$CC is not installed"
25068         fi
25069
25070         for header in $prefix/*.h; do
25071                 if ! [[ -f "$header" ]]; then
25072                         continue
25073                 fi
25074
25075                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25076                         continue # lustre_ioctl.h is internal header
25077                 fi
25078
25079                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25080                         error "cannot compile '$header'"
25081         done
25082         rm -f $out
25083 }
25084 run_test 400b "packaged headers can be compiled"
25085
25086 test_401a() { #LU-7437
25087         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25088         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25089
25090         #count the number of parameters by "list_param -R"
25091         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25092         #count the number of parameters by listing proc files
25093         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25094         echo "proc_dirs='$proc_dirs'"
25095         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25096         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25097                       sort -u | wc -l)
25098
25099         [ $params -eq $procs ] ||
25100                 error "found $params parameters vs. $procs proc files"
25101
25102         # test the list_param -D option only returns directories
25103         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25104         #count the number of parameters by listing proc directories
25105         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25106                 sort -u | wc -l)
25107
25108         [ $params -eq $procs ] ||
25109                 error "found $params parameters vs. $procs proc files"
25110 }
25111 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25112
25113 test_401b() {
25114         # jobid_var may not allow arbitrary values, so use jobid_name
25115         # if available
25116         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25117                 local testname=jobid_name tmp='testing%p'
25118         else
25119                 local testname=jobid_var tmp=testing
25120         fi
25121
25122         local save=$($LCTL get_param -n $testname)
25123
25124         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25125                 error "no error returned when setting bad parameters"
25126
25127         local jobid_new=$($LCTL get_param -n foe $testname baz)
25128         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25129
25130         $LCTL set_param -n fog=bam $testname=$save bat=fog
25131         local jobid_old=$($LCTL get_param -n foe $testname bag)
25132         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25133 }
25134 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25135
25136 test_401c() {
25137         # jobid_var may not allow arbitrary values, so use jobid_name
25138         # if available
25139         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25140                 local testname=jobid_name
25141         else
25142                 local testname=jobid_var
25143         fi
25144
25145         local jobid_var_old=$($LCTL get_param -n $testname)
25146         local jobid_var_new
25147
25148         $LCTL set_param $testname= &&
25149                 error "no error returned for 'set_param a='"
25150
25151         jobid_var_new=$($LCTL get_param -n $testname)
25152         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25153                 error "$testname was changed by setting without value"
25154
25155         $LCTL set_param $testname &&
25156                 error "no error returned for 'set_param a'"
25157
25158         jobid_var_new=$($LCTL get_param -n $testname)
25159         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25160                 error "$testname was changed by setting without value"
25161 }
25162 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25163
25164 test_401d() {
25165         # jobid_var may not allow arbitrary values, so use jobid_name
25166         # if available
25167         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25168                 local testname=jobid_name new_value='foo=bar%p'
25169         else
25170                 local testname=jobid_var new_valuie=foo=bar
25171         fi
25172
25173         local jobid_var_old=$($LCTL get_param -n $testname)
25174         local jobid_var_new
25175
25176         $LCTL set_param $testname=$new_value ||
25177                 error "'set_param a=b' did not accept a value containing '='"
25178
25179         jobid_var_new=$($LCTL get_param -n $testname)
25180         [[ "$jobid_var_new" == "$new_value" ]] ||
25181                 error "'set_param a=b' failed on a value containing '='"
25182
25183         # Reset the $testname to test the other format
25184         $LCTL set_param $testname=$jobid_var_old
25185         jobid_var_new=$($LCTL get_param -n $testname)
25186         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25187                 error "failed to reset $testname"
25188
25189         $LCTL set_param $testname $new_value ||
25190                 error "'set_param a b' did not accept a value containing '='"
25191
25192         jobid_var_new=$($LCTL get_param -n $testname)
25193         [[ "$jobid_var_new" == "$new_value" ]] ||
25194                 error "'set_param a b' failed on a value containing '='"
25195
25196         $LCTL set_param $testname $jobid_var_old
25197         jobid_var_new=$($LCTL get_param -n $testname)
25198         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25199                 error "failed to reset $testname"
25200 }
25201 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25202
25203 test_401e() { # LU-14779
25204         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25205                 error "lctl list_param MGC* failed"
25206         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25207         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25208                 error "lctl get_param lru_size failed"
25209 }
25210 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25211
25212 test_402() {
25213         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25214         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25215                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25216         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25217                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25218                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25219         remote_mds_nodsh && skip "remote MDS with nodsh"
25220
25221         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25222 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25223         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25224         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25225                 echo "Touch failed - OK"
25226 }
25227 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25228
25229 test_403() {
25230         local file1=$DIR/$tfile.1
25231         local file2=$DIR/$tfile.2
25232         local tfile=$TMP/$tfile
25233
25234         rm -f $file1 $file2 $tfile
25235
25236         touch $file1
25237         ln $file1 $file2
25238
25239         # 30 sec OBD_TIMEOUT in ll_getattr()
25240         # right before populating st_nlink
25241         $LCTL set_param fail_loc=0x80001409
25242         stat -c %h $file1 > $tfile &
25243
25244         # create an alias, drop all locks and reclaim the dentry
25245         < $file2
25246         cancel_lru_locks mdc
25247         cancel_lru_locks osc
25248         sysctl -w vm.drop_caches=2
25249
25250         wait
25251
25252         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25253
25254         rm -f $tfile $file1 $file2
25255 }
25256 run_test 403 "i_nlink should not drop to zero due to aliasing"
25257
25258 test_404() { # LU-6601
25259         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25260                 skip "Need server version newer than 2.8.52"
25261         remote_mds_nodsh && skip "remote MDS with nodsh"
25262
25263         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25264                 awk '/osp .*-osc-MDT/ { print $4}')
25265
25266         local osp
25267         for osp in $mosps; do
25268                 echo "Deactivate: " $osp
25269                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25270                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25271                         awk -vp=$osp '$4 == p { print $2 }')
25272                 [ $stat = IN ] || {
25273                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25274                         error "deactivate error"
25275                 }
25276                 echo "Activate: " $osp
25277                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25278                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25279                         awk -vp=$osp '$4 == p { print $2 }')
25280                 [ $stat = UP ] || {
25281                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25282                         error "activate error"
25283                 }
25284         done
25285 }
25286 run_test 404 "validate manual {de}activated works properly for OSPs"
25287
25288 test_405() {
25289         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25290         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25291                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25292                         skip "Layout swap lock is not supported"
25293
25294         check_swap_layouts_support
25295         check_swap_layout_no_dom $DIR
25296
25297         test_mkdir $DIR/$tdir
25298         swap_lock_test -d $DIR/$tdir ||
25299                 error "One layout swap locked test failed"
25300 }
25301 run_test 405 "Various layout swap lock tests"
25302
25303 test_406() {
25304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25305         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25306         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25308         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25309                 skip "Need MDS version at least 2.8.50"
25310
25311         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25312         local test_pool=$TESTNAME
25313
25314         pool_add $test_pool || error "pool_add failed"
25315         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25316                 error "pool_add_targets failed"
25317
25318         save_layout_restore_at_exit $MOUNT
25319
25320         # parent set default stripe count only, child will stripe from both
25321         # parent and fs default
25322         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25323                 error "setstripe $MOUNT failed"
25324         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25325         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25326         for i in $(seq 10); do
25327                 local f=$DIR/$tdir/$tfile.$i
25328                 touch $f || error "touch failed"
25329                 local count=$($LFS getstripe -c $f)
25330                 [ $count -eq $OSTCOUNT ] ||
25331                         error "$f stripe count $count != $OSTCOUNT"
25332                 local offset=$($LFS getstripe -i $f)
25333                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25334                 local size=$($LFS getstripe -S $f)
25335                 [ $size -eq $((def_stripe_size * 2)) ] ||
25336                         error "$f stripe size $size != $((def_stripe_size * 2))"
25337                 local pool=$($LFS getstripe -p $f)
25338                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25339         done
25340
25341         # change fs default striping, delete parent default striping, now child
25342         # will stripe from new fs default striping only
25343         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25344                 error "change $MOUNT default stripe failed"
25345         $LFS setstripe -c 0 $DIR/$tdir ||
25346                 error "delete $tdir default stripe failed"
25347         for i in $(seq 11 20); do
25348                 local f=$DIR/$tdir/$tfile.$i
25349                 touch $f || error "touch $f failed"
25350                 local count=$($LFS getstripe -c $f)
25351                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25352                 local offset=$($LFS getstripe -i $f)
25353                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25354                 local size=$($LFS getstripe -S $f)
25355                 [ $size -eq $def_stripe_size ] ||
25356                         error "$f stripe size $size != $def_stripe_size"
25357                 local pool=$($LFS getstripe -p $f)
25358                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25359         done
25360
25361         unlinkmany $DIR/$tdir/$tfile. 1 20
25362
25363         local f=$DIR/$tdir/$tfile
25364         pool_remove_all_targets $test_pool $f
25365         pool_remove $test_pool $f
25366 }
25367 run_test 406 "DNE support fs default striping"
25368
25369 test_407() {
25370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25371         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25372                 skip "Need MDS version at least 2.8.55"
25373         remote_mds_nodsh && skip "remote MDS with nodsh"
25374
25375         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25376                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25377         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25378                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25379         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25380
25381         #define OBD_FAIL_DT_TXN_STOP    0x2019
25382         for idx in $(seq $MDSCOUNT); do
25383                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25384         done
25385         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25386         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25387                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25388         true
25389 }
25390 run_test 407 "transaction fail should cause operation fail"
25391
25392 test_408() {
25393         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25394
25395         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25396         lctl set_param fail_loc=0x8000040a
25397         # let ll_prepare_partial_page() fail
25398         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25399
25400         rm -f $DIR/$tfile
25401
25402         # create at least 100 unused inodes so that
25403         # shrink_icache_memory(0) should not return 0
25404         touch $DIR/$tfile-{0..100}
25405         rm -f $DIR/$tfile-{0..100}
25406         sync
25407
25408         echo 2 > /proc/sys/vm/drop_caches
25409 }
25410 run_test 408 "drop_caches should not hang due to page leaks"
25411
25412 test_409()
25413 {
25414         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25415
25416         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25417         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25418         touch $DIR/$tdir/guard || error "(2) Fail to create"
25419
25420         local PREFIX=$(str_repeat 'A' 128)
25421         echo "Create 1K hard links start at $(date)"
25422         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25423                 error "(3) Fail to hard link"
25424
25425         echo "Links count should be right although linkEA overflow"
25426         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25427         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25428         [ $linkcount -eq 1001 ] ||
25429                 error "(5) Unexpected hard links count: $linkcount"
25430
25431         echo "List all links start at $(date)"
25432         ls -l $DIR/$tdir/foo > /dev/null ||
25433                 error "(6) Fail to list $DIR/$tdir/foo"
25434
25435         echo "Unlink hard links start at $(date)"
25436         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25437                 error "(7) Fail to unlink"
25438         echo "Unlink hard links finished at $(date)"
25439 }
25440 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25441
25442 test_410()
25443 {
25444         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25445                 skip "Need client version at least 2.9.59"
25446         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25447                 skip "Need MODULES build"
25448
25449         # Create a file, and stat it from the kernel
25450         local testfile=$DIR/$tfile
25451         touch $testfile
25452
25453         local run_id=$RANDOM
25454         local my_ino=$(stat --format "%i" $testfile)
25455
25456         # Try to insert the module. This will always fail as the
25457         # module is designed to not be inserted.
25458         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25459             &> /dev/null
25460
25461         # Anything but success is a test failure
25462         dmesg | grep -q \
25463             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25464             error "no inode match"
25465 }
25466 run_test 410 "Test inode number returned from kernel thread"
25467
25468 cleanup_test411_cgroup() {
25469         trap 0
25470         rmdir "$1"
25471 }
25472
25473 test_411() {
25474         local cg_basedir=/sys/fs/cgroup/memory
25475         # LU-9966
25476         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25477                 skip "no setup for cgroup"
25478
25479         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25480                 error "test file creation failed"
25481         cancel_lru_locks osc
25482
25483         # Create a very small memory cgroup to force a slab allocation error
25484         local cgdir=$cg_basedir/osc_slab_alloc
25485         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25486         trap "cleanup_test411_cgroup $cgdir" EXIT
25487         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25488         echo 1M > $cgdir/memory.limit_in_bytes
25489
25490         # Should not LBUG, just be killed by oom-killer
25491         # dd will return 0 even allocation failure in some environment.
25492         # So don't check return value
25493         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25494         cleanup_test411_cgroup $cgdir
25495
25496         return 0
25497 }
25498 run_test 411 "Slab allocation error with cgroup does not LBUG"
25499
25500 test_412() {
25501         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25502         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25503                 skip "Need server version at least 2.10.55"
25504
25505         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25506                 error "mkdir failed"
25507         $LFS getdirstripe $DIR/$tdir
25508         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25509         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25510                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25511         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25512         [ $stripe_count -eq 2 ] ||
25513                 error "expect 2 get $stripe_count"
25514
25515         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25516
25517         local index
25518         local index2
25519
25520         # subdirs should be on the same MDT as parent
25521         for i in $(seq 0 $((MDSCOUNT - 1))); do
25522                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25523                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25524                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25525                 (( index == i )) || error "mdt$i/sub on MDT$index"
25526         done
25527
25528         # stripe offset -1, ditto
25529         for i in {1..10}; do
25530                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25531                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25532                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25533                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25534                 (( index == index2 )) ||
25535                         error "qos$i on MDT$index, sub on MDT$index2"
25536         done
25537
25538         local testdir=$DIR/$tdir/inherit
25539
25540         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25541         # inherit 2 levels
25542         for i in 1 2; do
25543                 testdir=$testdir/s$i
25544                 mkdir $testdir || error "mkdir $testdir failed"
25545                 index=$($LFS getstripe -m $testdir)
25546                 (( index == 1 )) ||
25547                         error "$testdir on MDT$index"
25548         done
25549
25550         # not inherit any more
25551         testdir=$testdir/s3
25552         mkdir $testdir || error "mkdir $testdir failed"
25553         getfattr -d -m dmv $testdir | grep dmv &&
25554                 error "default LMV set on $testdir" || true
25555 }
25556 run_test 412 "mkdir on specific MDTs"
25557
25558 generate_uneven_mdts() {
25559         local threshold=$1
25560         local lmv_qos_maxage
25561         local lod_qos_maxage
25562         local ffree
25563         local bavail
25564         local max
25565         local min
25566         local max_index
25567         local min_index
25568         local tmp
25569         local i
25570
25571         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25572         $LCTL set_param lmv.*.qos_maxage=1
25573         stack_trap "$LCTL set_param \
25574                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25575         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25576                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25577         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25578                 lod.*.mdt_qos_maxage=1
25579         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25580                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25581
25582         echo
25583         echo "Check for uneven MDTs: "
25584
25585         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25586         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25587         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25588
25589         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25590         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25591         max_index=0
25592         min_index=0
25593         for ((i = 1; i < ${#ffree[@]}; i++)); do
25594                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25595                 if [ $tmp -gt $max ]; then
25596                         max=$tmp
25597                         max_index=$i
25598                 fi
25599                 if [ $tmp -lt $min ]; then
25600                         min=$tmp
25601                         min_index=$i
25602                 fi
25603         done
25604
25605         (( ${ffree[min_index]} > 0 )) ||
25606                 skip "no free files in MDT$min_index"
25607         (( ${ffree[min_index]} < 10000000 )) ||
25608                 skip "too many free files in MDT$min_index"
25609
25610         # Check if we need to generate uneven MDTs
25611         local diff=$(((max - min) * 100 / min))
25612         local testdir=$DIR/$tdir-fillmdt
25613         local start
25614
25615         mkdir -p $testdir
25616
25617         i=0
25618         while (( diff < threshold )); do
25619                 # generate uneven MDTs, create till $threshold% diff
25620                 echo -n "weight diff=$diff% must be > $threshold% ..."
25621                 echo "Fill MDT$min_index with 1000 files: loop $i"
25622                 testdir=$DIR/$tdir-fillmdt/$i
25623                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25624                         error "mkdir $testdir failed"
25625                 $LFS setstripe -E 1M -L mdt $testdir ||
25626                         error "setstripe $testdir failed"
25627                 start=$SECONDS
25628                 for F in f.{0..999}; do
25629                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25630                                 /dev/null 2>&1 || error "dd $F failed"
25631                 done
25632
25633                 # wait for QOS to update
25634                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25635
25636                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25637                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25638                 max=$(((${ffree[max_index]} >> 8) *
25639                         (${bavail[max_index]} * bsize >> 16)))
25640                 min=$(((${ffree[min_index]} >> 8) *
25641                         (${bavail[min_index]} * bsize >> 16)))
25642                 diff=$(((max - min) * 100 / min))
25643                 i=$((i + 1))
25644         done
25645
25646         echo "MDT filesfree available: ${ffree[*]}"
25647         echo "MDT blocks available: ${bavail[*]}"
25648         echo "weight diff=$diff%"
25649 }
25650
25651 test_qos_mkdir() {
25652         local mkdir_cmd=$1
25653         local stripe_count=$2
25654         local mdts=$(comma_list $(mdts_nodes))
25655
25656         local testdir
25657         local lmv_qos_prio_free
25658         local lmv_qos_threshold_rr
25659         local lmv_qos_maxage
25660         local lod_qos_prio_free
25661         local lod_qos_threshold_rr
25662         local lod_qos_maxage
25663         local count
25664         local i
25665
25666         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25667         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25668         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25669                 head -n1)
25670         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25671         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25672         stack_trap "$LCTL set_param \
25673                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25674         stack_trap "$LCTL set_param \
25675                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25676         stack_trap "$LCTL set_param \
25677                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25678
25679         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25680                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25681         lod_qos_prio_free=${lod_qos_prio_free%%%}
25682         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25683                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25684         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25685         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25686                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25687         stack_trap "do_nodes $mdts $LCTL set_param \
25688                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25689         stack_trap "do_nodes $mdts $LCTL set_param \
25690                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25691         stack_trap "do_nodes $mdts $LCTL set_param \
25692                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25693
25694         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25695         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25696
25697         testdir=$DIR/$tdir-s$stripe_count/rr
25698
25699         local stripe_index=$($LFS getstripe -m $testdir)
25700         local test_mkdir_rr=true
25701
25702         getfattr -d -m dmv -e hex $testdir | grep dmv
25703         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25704                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25705                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25706                         test_mkdir_rr=false
25707         fi
25708
25709         echo
25710         $test_mkdir_rr &&
25711                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25712                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25713
25714         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25715         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25716                 eval $mkdir_cmd $testdir/subdir$i ||
25717                         error "$mkdir_cmd subdir$i failed"
25718         done
25719
25720         for (( i = 0; i < $MDSCOUNT; i++ )); do
25721                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25722                 echo "$count directories created on MDT$i"
25723                 if $test_mkdir_rr; then
25724                         (( $count == 100 )) ||
25725                                 error "subdirs are not evenly distributed"
25726                 elif (( $i == $stripe_index )); then
25727                         (( $count == 100 * MDSCOUNT )) ||
25728                                 error "$count subdirs created on MDT$i"
25729                 else
25730                         (( $count == 0 )) ||
25731                                 error "$count subdirs created on MDT$i"
25732                 fi
25733
25734                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25735                         count=$($LFS getdirstripe $testdir/* |
25736                                 grep -c -P "^\s+$i\t")
25737                         echo "$count stripes created on MDT$i"
25738                         # deviation should < 5% of average
25739                         (( $count >= 95 * stripe_count &&
25740                            $count <= 105 * stripe_count)) ||
25741                                 error "stripes are not evenly distributed"
25742                 fi
25743         done
25744
25745         echo
25746         echo "Check for uneven MDTs: "
25747
25748         local ffree
25749         local bavail
25750         local max
25751         local min
25752         local max_index
25753         local min_index
25754         local tmp
25755
25756         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25757         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25758         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25759
25760         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25761         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25762         max_index=0
25763         min_index=0
25764         for ((i = 1; i < ${#ffree[@]}; i++)); do
25765                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25766                 if [ $tmp -gt $max ]; then
25767                         max=$tmp
25768                         max_index=$i
25769                 fi
25770                 if [ $tmp -lt $min ]; then
25771                         min=$tmp
25772                         min_index=$i
25773                 fi
25774         done
25775
25776         (( ${ffree[min_index]} > 0 )) ||
25777                 skip "no free files in MDT$min_index"
25778         (( ${ffree[min_index]} < 10000000 )) ||
25779                 skip "too many free files in MDT$min_index"
25780
25781         echo "MDT filesfree available: ${ffree[*]}"
25782         echo "MDT blocks available: ${bavail[*]}"
25783         echo "weight diff=$(((max - min) * 100 / min))%"
25784         echo
25785         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25786
25787         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25788         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25789         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25790         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25791         # decrease statfs age, so that it can be updated in time
25792         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25793         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25794
25795         sleep 1
25796
25797         testdir=$DIR/$tdir-s$stripe_count/qos
25798         local num=200
25799
25800         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25801         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25802                 eval $mkdir_cmd $testdir/subdir$i ||
25803                         error "$mkdir_cmd subdir$i failed"
25804         done
25805
25806         max=0
25807         for (( i = 0; i < $MDSCOUNT; i++ )); do
25808                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25809                 (( count > max )) && max=$count
25810                 echo "$count directories created on MDT$i"
25811         done
25812
25813         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25814
25815         # D-value should > 10% of averge
25816         (( max - min > num / 10 )) ||
25817                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25818
25819         # ditto for stripes
25820         if (( stripe_count > 1 )); then
25821                 max=0
25822                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25823                         count=$($LFS getdirstripe $testdir/* |
25824                                 grep -c -P "^\s+$i\t")
25825                         (( count > max )) && max=$count
25826                         echo "$count stripes created on MDT$i"
25827                 done
25828
25829                 min=$($LFS getdirstripe $testdir/* |
25830                         grep -c -P "^\s+$min_index\t")
25831                 (( max - min > num * stripe_count / 10 )) ||
25832                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25833         fi
25834 }
25835
25836 most_full_mdt() {
25837         local ffree
25838         local bavail
25839         local bsize
25840         local min
25841         local min_index
25842         local tmp
25843
25844         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25845         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25846         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25847
25848         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25849         min_index=0
25850         for ((i = 1; i < ${#ffree[@]}; i++)); do
25851                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25852                 (( tmp < min )) && min=$tmp && min_index=$i
25853         done
25854
25855         echo -n $min_index
25856 }
25857
25858 test_413a() {
25859         [ $MDSCOUNT -lt 2 ] &&
25860                 skip "We need at least 2 MDTs for this test"
25861
25862         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25863                 skip "Need server version at least 2.12.52"
25864
25865         local stripe_count
25866
25867         generate_uneven_mdts 100
25868         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25869                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25870                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25871                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25872                         error "mkdir failed"
25873                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25874         done
25875 }
25876 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25877
25878 test_413b() {
25879         [ $MDSCOUNT -lt 2 ] &&
25880                 skip "We need at least 2 MDTs for this test"
25881
25882         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25883                 skip "Need server version at least 2.12.52"
25884
25885         local testdir
25886         local stripe_count
25887
25888         generate_uneven_mdts 100
25889         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25890                 testdir=$DIR/$tdir-s$stripe_count
25891                 mkdir $testdir || error "mkdir $testdir failed"
25892                 mkdir $testdir/rr || error "mkdir rr failed"
25893                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25894                         error "mkdir qos failed"
25895                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25896                         $testdir/rr || error "setdirstripe rr failed"
25897                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25898                         error "setdirstripe failed"
25899                 test_qos_mkdir "mkdir" $stripe_count
25900         done
25901 }
25902 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25903
25904 test_413c() {
25905         (( $MDSCOUNT >= 2 )) ||
25906                 skip "We need at least 2 MDTs for this test"
25907
25908         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25909                 skip "Need server version at least 2.14.51"
25910
25911         local testdir
25912         local inherit
25913         local inherit_rr
25914
25915         testdir=$DIR/${tdir}-s1
25916         mkdir $testdir || error "mkdir $testdir failed"
25917         mkdir $testdir/rr || error "mkdir rr failed"
25918         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25919         # default max_inherit is -1, default max_inherit_rr is 0
25920         $LFS setdirstripe -D -c 1 $testdir/rr ||
25921                 error "setdirstripe rr failed"
25922         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25923                 error "setdirstripe qos failed"
25924         test_qos_mkdir "mkdir" 1
25925
25926         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25927         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25928         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25929         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25930         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25931
25932         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25933         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25934         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25935         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25936         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25937         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25938         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25939                 error "level2 shouldn't have default LMV" || true
25940 }
25941 run_test 413c "mkdir with default LMV max inherit rr"
25942
25943 test_413d() {
25944         (( MDSCOUNT >= 2 )) ||
25945                 skip "We need at least 2 MDTs for this test"
25946
25947         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25948                 skip "Need server version at least 2.14.51"
25949
25950         local lmv_qos_threshold_rr
25951
25952         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25953                 head -n1)
25954         stack_trap "$LCTL set_param \
25955                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25956
25957         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25958         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25959         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25960                 error "$tdir shouldn't have default LMV"
25961         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25962                 error "mkdir sub failed"
25963
25964         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25965
25966         (( count == 100 )) || error "$count subdirs on MDT0"
25967 }
25968 run_test 413d "inherit ROOT default LMV"
25969
25970 test_413e() {
25971         (( MDSCOUNT >= 2 )) ||
25972                 skip "We need at least 2 MDTs for this test"
25973         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25974                 skip "Need server version at least 2.14.55"
25975
25976         local testdir=$DIR/$tdir
25977         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25978         local max_inherit
25979         local sub_max_inherit
25980
25981         mkdir -p $testdir || error "failed to create $testdir"
25982
25983         # set default max-inherit to -1 if stripe count is 0 or 1
25984         $LFS setdirstripe -D -c 1 $testdir ||
25985                 error "failed to set default LMV"
25986         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25987         (( max_inherit == -1 )) ||
25988                 error "wrong max_inherit value $max_inherit"
25989
25990         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25991         $LFS setdirstripe -D -c -1 $testdir ||
25992                 error "failed to set default LMV"
25993         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25994         (( max_inherit > 0 )) ||
25995                 error "wrong max_inherit value $max_inherit"
25996
25997         # and the subdir will decrease the max_inherit by 1
25998         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25999         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26000         (( sub_max_inherit == max_inherit - 1)) ||
26001                 error "wrong max-inherit of subdir $sub_max_inherit"
26002
26003         # check specified --max-inherit and warning message
26004         stack_trap "rm -f $tmpfile"
26005         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26006                 error "failed to set default LMV"
26007         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26008         (( max_inherit == -1 )) ||
26009                 error "wrong max_inherit value $max_inherit"
26010
26011         # check the warning messages
26012         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26013                 error "failed to detect warning string"
26014         fi
26015 }
26016 run_test 413e "check default max-inherit value"
26017
26018 test_fs_dmv_inherit()
26019 {
26020         local testdir=$DIR/$tdir
26021
26022         local count
26023         local inherit
26024         local inherit_rr
26025
26026         for i in 1 2 3; do
26027                 mkdir $testdir || error "mkdir $testdir failed"
26028                 count=$($LFS getdirstripe -D -c $testdir)
26029                 (( count == 1 )) ||
26030                         error "$testdir default LMV count mismatch $count != 1"
26031                 inherit=$($LFS getdirstripe -D -X $testdir)
26032                 (( inherit == 3 - i )) ||
26033                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26034                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26035                 (( inherit_rr == 3 - i )) ||
26036                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26037                 testdir=$testdir/sub
26038         done
26039
26040         mkdir $testdir || error "mkdir $testdir failed"
26041         count=$($LFS getdirstripe -D -c $testdir)
26042         (( count == 0 )) ||
26043                 error "$testdir default LMV count not zero: $count"
26044 }
26045
26046 test_413f() {
26047         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26048
26049         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26050                 skip "Need server version at least 2.14.55"
26051
26052         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26053                 error "dump $DIR default LMV failed"
26054         stack_trap "setfattr --restore=$TMP/dmv.ea"
26055
26056         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26057                 error "set $DIR default LMV failed"
26058
26059         test_fs_dmv_inherit
26060 }
26061 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26062
26063 test_413g() {
26064         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26065
26066         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26067         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26068                 error "dump $DIR default LMV failed"
26069         stack_trap "setfattr --restore=$TMP/dmv.ea"
26070
26071         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26072                 error "set $DIR default LMV failed"
26073
26074         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26075                 error "mount $MOUNT2 failed"
26076         stack_trap "umount_client $MOUNT2"
26077
26078         local saved_DIR=$DIR
26079
26080         export DIR=$MOUNT2
26081
26082         stack_trap "export DIR=$saved_DIR"
26083
26084         # first check filesystem-wide default LMV inheritance
26085         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26086
26087         # then check subdirs are spread to all MDTs
26088         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26089
26090         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26091
26092         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26093 }
26094 run_test 413g "enforce ROOT default LMV on subdir mount"
26095
26096 test_413z() {
26097         local pids=""
26098         local subdir
26099         local pid
26100
26101         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26102                 unlinkmany $subdir/f. 1000 &
26103                 pids="$pids $!"
26104         done
26105
26106         for pid in $pids; do
26107                 wait $pid
26108         done
26109 }
26110 run_test 413z "413 test cleanup"
26111
26112 test_414() {
26113 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26114         $LCTL set_param fail_loc=0x80000521
26115         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26116         rm -f $DIR/$tfile
26117 }
26118 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26119
26120 test_415() {
26121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26122         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26123                 skip "Need server version at least 2.11.52"
26124
26125         # LU-11102
26126         local total
26127         local setattr_pid
26128         local start_time
26129         local end_time
26130         local duration
26131
26132         total=500
26133         # this test may be slow on ZFS
26134         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26135
26136         # though this test is designed for striped directory, let's test normal
26137         # directory too since lock is always saved as CoS lock.
26138         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26139         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26140
26141         (
26142                 while true; do
26143                         touch $DIR/$tdir
26144                 done
26145         ) &
26146         setattr_pid=$!
26147
26148         start_time=$(date +%s)
26149         for i in $(seq $total); do
26150                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26151                         > /dev/null
26152         done
26153         end_time=$(date +%s)
26154         duration=$((end_time - start_time))
26155
26156         kill -9 $setattr_pid
26157
26158         echo "rename $total files took $duration sec"
26159         [ $duration -lt 100 ] || error "rename took $duration sec"
26160 }
26161 run_test 415 "lock revoke is not missing"
26162
26163 test_416() {
26164         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26165                 skip "Need server version at least 2.11.55"
26166
26167         # define OBD_FAIL_OSD_TXN_START    0x19a
26168         do_facet mds1 lctl set_param fail_loc=0x19a
26169
26170         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26171
26172         true
26173 }
26174 run_test 416 "transaction start failure won't cause system hung"
26175
26176 cleanup_417() {
26177         trap 0
26178         do_nodes $(comma_list $(mdts_nodes)) \
26179                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26180         do_nodes $(comma_list $(mdts_nodes)) \
26181                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26182         do_nodes $(comma_list $(mdts_nodes)) \
26183                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26184 }
26185
26186 test_417() {
26187         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26188         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26189                 skip "Need MDS version at least 2.11.56"
26190
26191         trap cleanup_417 RETURN EXIT
26192
26193         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26194         do_nodes $(comma_list $(mdts_nodes)) \
26195                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26196         $LFS migrate -m 0 $DIR/$tdir.1 &&
26197                 error "migrate dir $tdir.1 should fail"
26198
26199         do_nodes $(comma_list $(mdts_nodes)) \
26200                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26201         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26202                 error "create remote dir $tdir.2 should fail"
26203
26204         do_nodes $(comma_list $(mdts_nodes)) \
26205                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26206         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26207                 error "create striped dir $tdir.3 should fail"
26208         true
26209 }
26210 run_test 417 "disable remote dir, striped dir and dir migration"
26211
26212 # Checks that the outputs of df [-i] and lfs df [-i] match
26213 #
26214 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26215 check_lfs_df() {
26216         local dir=$2
26217         local inodes
26218         local df_out
26219         local lfs_df_out
26220         local count
26221         local passed=false
26222
26223         # blocks or inodes
26224         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26225
26226         for count in {1..100}; do
26227                 do_nodes "$CLIENTS" \
26228                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26229                 sync; sleep 0.2
26230
26231                 # read the lines of interest
26232                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26233                         error "df $inodes $dir | tail -n +2 failed"
26234                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26235                         error "lfs df $inodes $dir | grep summary: failed"
26236
26237                 # skip first substrings of each output as they are different
26238                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26239                 # compare the two outputs
26240                 passed=true
26241                 #  skip "available" on MDT until LU-13997 is fixed.
26242                 #for i in {1..5}; do
26243                 for i in 1 2 4 5; do
26244                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26245                 done
26246                 $passed && break
26247         done
26248
26249         if ! $passed; then
26250                 df -P $inodes $dir
26251                 echo
26252                 lfs df $inodes $dir
26253                 error "df and lfs df $1 output mismatch: "      \
26254                       "df ${inodes}: ${df_out[*]}, "            \
26255                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26256         fi
26257 }
26258
26259 test_418() {
26260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26261
26262         local dir=$DIR/$tdir
26263         local numfiles=$((RANDOM % 4096 + 2))
26264         local numblocks=$((RANDOM % 256 + 1))
26265
26266         wait_delete_completed
26267         test_mkdir $dir
26268
26269         # check block output
26270         check_lfs_df blocks $dir
26271         # check inode output
26272         check_lfs_df inodes $dir
26273
26274         # create a single file and retest
26275         echo "Creating a single file and testing"
26276         createmany -o $dir/$tfile- 1 &>/dev/null ||
26277                 error "creating 1 file in $dir failed"
26278         check_lfs_df blocks $dir
26279         check_lfs_df inodes $dir
26280
26281         # create a random number of files
26282         echo "Creating $((numfiles - 1)) files and testing"
26283         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26284                 error "creating $((numfiles - 1)) files in $dir failed"
26285
26286         # write a random number of blocks to the first test file
26287         echo "Writing $numblocks 4K blocks and testing"
26288         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26289                 count=$numblocks &>/dev/null ||
26290                 error "dd to $dir/${tfile}-0 failed"
26291
26292         # retest
26293         check_lfs_df blocks $dir
26294         check_lfs_df inodes $dir
26295
26296         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26297                 error "unlinking $numfiles files in $dir failed"
26298 }
26299 run_test 418 "df and lfs df outputs match"
26300
26301 test_419()
26302 {
26303         local dir=$DIR/$tdir
26304
26305         mkdir -p $dir
26306         touch $dir/file
26307
26308         cancel_lru_locks mdc
26309
26310         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26311         $LCTL set_param fail_loc=0x1410
26312         cat $dir/file
26313         $LCTL set_param fail_loc=0
26314         rm -rf $dir
26315 }
26316 run_test 419 "Verify open file by name doesn't crash kernel"
26317
26318 test_420()
26319 {
26320         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26321                 skip "Need MDS version at least 2.12.53"
26322
26323         local SAVE_UMASK=$(umask)
26324         local dir=$DIR/$tdir
26325         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26326
26327         mkdir -p $dir
26328         umask 0000
26329         mkdir -m03777 $dir/testdir
26330         ls -dn $dir/testdir
26331         # Need to remove trailing '.' when SELinux is enabled
26332         local dirperms=$(ls -dn $dir/testdir |
26333                          awk '{ sub(/\.$/, "", $1); print $1}')
26334         [ $dirperms == "drwxrwsrwt" ] ||
26335                 error "incorrect perms on $dir/testdir"
26336
26337         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26338                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26339         ls -n $dir/testdir/testfile
26340         local fileperms=$(ls -n $dir/testdir/testfile |
26341                           awk '{ sub(/\.$/, "", $1); print $1}')
26342         [ $fileperms == "-rwxr-xr-x" ] ||
26343                 error "incorrect perms on $dir/testdir/testfile"
26344
26345         umask $SAVE_UMASK
26346 }
26347 run_test 420 "clear SGID bit on non-directories for non-members"
26348
26349 test_421a() {
26350         local cnt
26351         local fid1
26352         local fid2
26353
26354         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26355                 skip "Need MDS version at least 2.12.54"
26356
26357         test_mkdir $DIR/$tdir
26358         createmany -o $DIR/$tdir/f 3
26359         cnt=$(ls -1 $DIR/$tdir | wc -l)
26360         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26361
26362         fid1=$(lfs path2fid $DIR/$tdir/f1)
26363         fid2=$(lfs path2fid $DIR/$tdir/f2)
26364         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26365
26366         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26367         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26368
26369         cnt=$(ls -1 $DIR/$tdir | wc -l)
26370         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26371
26372         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26373         createmany -o $DIR/$tdir/f 3
26374         cnt=$(ls -1 $DIR/$tdir | wc -l)
26375         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26376
26377         fid1=$(lfs path2fid $DIR/$tdir/f1)
26378         fid2=$(lfs path2fid $DIR/$tdir/f2)
26379         echo "remove using fsname $FSNAME"
26380         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26381
26382         cnt=$(ls -1 $DIR/$tdir | wc -l)
26383         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26384 }
26385 run_test 421a "simple rm by fid"
26386
26387 test_421b() {
26388         local cnt
26389         local FID1
26390         local FID2
26391
26392         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26393                 skip "Need MDS version at least 2.12.54"
26394
26395         test_mkdir $DIR/$tdir
26396         createmany -o $DIR/$tdir/f 3
26397         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26398         MULTIPID=$!
26399
26400         FID1=$(lfs path2fid $DIR/$tdir/f1)
26401         FID2=$(lfs path2fid $DIR/$tdir/f2)
26402         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26403
26404         kill -USR1 $MULTIPID
26405         wait
26406
26407         cnt=$(ls $DIR/$tdir | wc -l)
26408         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26409 }
26410 run_test 421b "rm by fid on open file"
26411
26412 test_421c() {
26413         local cnt
26414         local FIDS
26415
26416         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26417                 skip "Need MDS version at least 2.12.54"
26418
26419         test_mkdir $DIR/$tdir
26420         createmany -o $DIR/$tdir/f 3
26421         touch $DIR/$tdir/$tfile
26422         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26423         cnt=$(ls -1 $DIR/$tdir | wc -l)
26424         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26425
26426         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26427         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26428
26429         cnt=$(ls $DIR/$tdir | wc -l)
26430         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26431 }
26432 run_test 421c "rm by fid against hardlinked files"
26433
26434 test_421d() {
26435         local cnt
26436         local FIDS
26437
26438         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26439                 skip "Need MDS version at least 2.12.54"
26440
26441         test_mkdir $DIR/$tdir
26442         createmany -o $DIR/$tdir/f 4097
26443         cnt=$(ls -1 $DIR/$tdir | wc -l)
26444         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26445
26446         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26447         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26448
26449         cnt=$(ls $DIR/$tdir | wc -l)
26450         rm -rf $DIR/$tdir
26451         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26452 }
26453 run_test 421d "rmfid en masse"
26454
26455 test_421e() {
26456         local cnt
26457         local FID
26458
26459         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26460         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26461                 skip "Need MDS version at least 2.12.54"
26462
26463         mkdir -p $DIR/$tdir
26464         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26465         createmany -o $DIR/$tdir/striped_dir/f 512
26466         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26467         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26468
26469         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26470                 sed "s/[/][^:]*://g")
26471         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26472
26473         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26474         rm -rf $DIR/$tdir
26475         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26476 }
26477 run_test 421e "rmfid in DNE"
26478
26479 test_421f() {
26480         local cnt
26481         local FID
26482
26483         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26484                 skip "Need MDS version at least 2.12.54"
26485
26486         test_mkdir $DIR/$tdir
26487         touch $DIR/$tdir/f
26488         cnt=$(ls -1 $DIR/$tdir | wc -l)
26489         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26490
26491         FID=$(lfs path2fid $DIR/$tdir/f)
26492         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26493         # rmfid should fail
26494         cnt=$(ls -1 $DIR/$tdir | wc -l)
26495         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26496
26497         chmod a+rw $DIR/$tdir
26498         ls -la $DIR/$tdir
26499         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26500         # rmfid should fail
26501         cnt=$(ls -1 $DIR/$tdir | wc -l)
26502         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26503
26504         rm -f $DIR/$tdir/f
26505         $RUNAS touch $DIR/$tdir/f
26506         FID=$(lfs path2fid $DIR/$tdir/f)
26507         echo "rmfid as root"
26508         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26509         cnt=$(ls -1 $DIR/$tdir | wc -l)
26510         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26511
26512         rm -f $DIR/$tdir/f
26513         $RUNAS touch $DIR/$tdir/f
26514         cnt=$(ls -1 $DIR/$tdir | wc -l)
26515         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26516         FID=$(lfs path2fid $DIR/$tdir/f)
26517         # rmfid w/o user_fid2path mount option should fail
26518         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26519         cnt=$(ls -1 $DIR/$tdir | wc -l)
26520         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26521
26522         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26523         stack_trap "rmdir $tmpdir"
26524         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26525                 error "failed to mount client'"
26526         stack_trap "umount_client $tmpdir"
26527
26528         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26529         # rmfid should succeed
26530         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26531         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26532
26533         # rmfid shouldn't allow to remove files due to dir's permission
26534         chmod a+rwx $tmpdir/$tdir
26535         touch $tmpdir/$tdir/f
26536         ls -la $tmpdir/$tdir
26537         FID=$(lfs path2fid $tmpdir/$tdir/f)
26538         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26539         return 0
26540 }
26541 run_test 421f "rmfid checks permissions"
26542
26543 test_421g() {
26544         local cnt
26545         local FIDS
26546
26547         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26548         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26549                 skip "Need MDS version at least 2.12.54"
26550
26551         mkdir -p $DIR/$tdir
26552         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26553         createmany -o $DIR/$tdir/striped_dir/f 512
26554         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26555         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26556
26557         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26558                 sed "s/[/][^:]*://g")
26559
26560         rm -f $DIR/$tdir/striped_dir/f1*
26561         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26562         removed=$((512 - cnt))
26563
26564         # few files have been just removed, so we expect
26565         # rmfid to fail on their fids
26566         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26567         [ $removed != $errors ] && error "$errors != $removed"
26568
26569         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26570         rm -rf $DIR/$tdir
26571         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26572 }
26573 run_test 421g "rmfid to return errors properly"
26574
26575 test_422() {
26576         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26577         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26578         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26579         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26580         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26581
26582         local amc=$(at_max_get client)
26583         local amo=$(at_max_get mds1)
26584         local timeout=`lctl get_param -n timeout`
26585
26586         at_max_set 0 client
26587         at_max_set 0 mds1
26588
26589 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26590         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26591                         fail_val=$(((2*timeout + 10)*1000))
26592         touch $DIR/$tdir/d3/file &
26593         sleep 2
26594 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26595         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26596                         fail_val=$((2*timeout + 5))
26597         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26598         local pid=$!
26599         sleep 1
26600         kill -9 $pid
26601         sleep $((2 * timeout))
26602         echo kill $pid
26603         kill -9 $pid
26604         lctl mark touch
26605         touch $DIR/$tdir/d2/file3
26606         touch $DIR/$tdir/d2/file4
26607         touch $DIR/$tdir/d2/file5
26608
26609         wait
26610         at_max_set $amc client
26611         at_max_set $amo mds1
26612
26613         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26614         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26615                 error "Watchdog is always throttled"
26616 }
26617 run_test 422 "kill a process with RPC in progress"
26618
26619 stat_test() {
26620     df -h $MOUNT &
26621     df -h $MOUNT &
26622     df -h $MOUNT &
26623     df -h $MOUNT &
26624     df -h $MOUNT &
26625     df -h $MOUNT &
26626 }
26627
26628 test_423() {
26629     local _stats
26630     # ensure statfs cache is expired
26631     sleep 2;
26632
26633     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26634     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26635
26636     return 0
26637 }
26638 run_test 423 "statfs should return a right data"
26639
26640 test_424() {
26641 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26642         $LCTL set_param fail_loc=0x80000522
26643         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26644         rm -f $DIR/$tfile
26645 }
26646 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26647
26648 test_425() {
26649         test_mkdir -c -1 $DIR/$tdir
26650         $LFS setstripe -c -1 $DIR/$tdir
26651
26652         lru_resize_disable "" 100
26653         stack_trap "lru_resize_enable" EXIT
26654
26655         sleep 5
26656
26657         for i in $(seq $((MDSCOUNT * 125))); do
26658                 local t=$DIR/$tdir/$tfile_$i
26659
26660                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26661                         error_noexit "Create file $t"
26662         done
26663         stack_trap "rm -rf $DIR/$tdir" EXIT
26664
26665         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26666                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26667                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26668
26669                 [ $lock_count -le $lru_size ] ||
26670                         error "osc lock count $lock_count > lru size $lru_size"
26671         done
26672
26673         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26674                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26675                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26676
26677                 [ $lock_count -le $lru_size ] ||
26678                         error "mdc lock count $lock_count > lru size $lru_size"
26679         done
26680 }
26681 run_test 425 "lock count should not exceed lru size"
26682
26683 test_426() {
26684         splice-test -r $DIR/$tfile
26685         splice-test -rd $DIR/$tfile
26686         splice-test $DIR/$tfile
26687         splice-test -d $DIR/$tfile
26688 }
26689 run_test 426 "splice test on Lustre"
26690
26691 test_427() {
26692         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26693         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26694                 skip "Need MDS version at least 2.12.4"
26695         local log
26696
26697         mkdir $DIR/$tdir
26698         mkdir $DIR/$tdir/1
26699         mkdir $DIR/$tdir/2
26700         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26701         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26702
26703         $LFS getdirstripe $DIR/$tdir/1/dir
26704
26705         #first setfattr for creating updatelog
26706         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26707
26708 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26709         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26710         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26711         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26712
26713         sleep 2
26714         fail mds2
26715         wait_recovery_complete mds2 $((2*TIMEOUT))
26716
26717         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26718         echo $log | grep "get update log failed" &&
26719                 error "update log corruption is detected" || true
26720 }
26721 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26722
26723 test_428() {
26724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26725         local cache_limit=$CACHE_MAX
26726
26727         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26728         $LCTL set_param -n llite.*.max_cached_mb=64
26729
26730         mkdir $DIR/$tdir
26731         $LFS setstripe -c 1 $DIR/$tdir
26732         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26733         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26734         #test write
26735         for f in $(seq 4); do
26736                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26737         done
26738         wait
26739
26740         cancel_lru_locks osc
26741         # Test read
26742         for f in $(seq 4); do
26743                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26744         done
26745         wait
26746 }
26747 run_test 428 "large block size IO should not hang"
26748
26749 test_429() { # LU-7915 / LU-10948
26750         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26751         local testfile=$DIR/$tfile
26752         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26753         local new_flag=1
26754         local first_rpc
26755         local second_rpc
26756         local third_rpc
26757
26758         $LCTL get_param $ll_opencache_threshold_count ||
26759                 skip "client does not have opencache parameter"
26760
26761         set_opencache $new_flag
26762         stack_trap "restore_opencache"
26763         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26764                 error "enable opencache failed"
26765         touch $testfile
26766         # drop MDC DLM locks
26767         cancel_lru_locks mdc
26768         # clear MDC RPC stats counters
26769         $LCTL set_param $mdc_rpcstats=clear
26770
26771         # According to the current implementation, we need to run 3 times
26772         # open & close file to verify if opencache is enabled correctly.
26773         # 1st, RPCs are sent for lookup/open and open handle is released on
26774         #      close finally.
26775         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26776         #      so open handle won't be released thereafter.
26777         # 3rd, No RPC is sent out.
26778         $MULTIOP $testfile oc || error "multiop failed"
26779         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26780         echo "1st: $first_rpc RPCs in flight"
26781
26782         $MULTIOP $testfile oc || error "multiop failed"
26783         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26784         echo "2nd: $second_rpc RPCs in flight"
26785
26786         $MULTIOP $testfile oc || error "multiop failed"
26787         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26788         echo "3rd: $third_rpc RPCs in flight"
26789
26790         #verify no MDC RPC is sent
26791         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26792 }
26793 run_test 429 "verify if opencache flag on client side does work"
26794
26795 lseek_test_430() {
26796         local offset
26797         local file=$1
26798
26799         # data at [200K, 400K)
26800         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26801                 error "256K->512K dd fails"
26802         # data at [2M, 3M)
26803         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26804                 error "2M->3M dd fails"
26805         # data at [4M, 5M)
26806         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26807                 error "4M->5M dd fails"
26808         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26809         # start at first component hole #1
26810         printf "Seeking hole from 1000 ... "
26811         offset=$(lseek_test -l 1000 $file)
26812         echo $offset
26813         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26814         printf "Seeking data from 1000 ... "
26815         offset=$(lseek_test -d 1000 $file)
26816         echo $offset
26817         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26818
26819         # start at first component data block
26820         printf "Seeking hole from 300000 ... "
26821         offset=$(lseek_test -l 300000 $file)
26822         echo $offset
26823         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26824         printf "Seeking data from 300000 ... "
26825         offset=$(lseek_test -d 300000 $file)
26826         echo $offset
26827         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26828
26829         # start at the first component but beyond end of object size
26830         printf "Seeking hole from 1000000 ... "
26831         offset=$(lseek_test -l 1000000 $file)
26832         echo $offset
26833         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26834         printf "Seeking data from 1000000 ... "
26835         offset=$(lseek_test -d 1000000 $file)
26836         echo $offset
26837         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26838
26839         # start at second component stripe 2 (empty file)
26840         printf "Seeking hole from 1500000 ... "
26841         offset=$(lseek_test -l 1500000 $file)
26842         echo $offset
26843         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26844         printf "Seeking data from 1500000 ... "
26845         offset=$(lseek_test -d 1500000 $file)
26846         echo $offset
26847         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26848
26849         # start at second component stripe 1 (all data)
26850         printf "Seeking hole from 3000000 ... "
26851         offset=$(lseek_test -l 3000000 $file)
26852         echo $offset
26853         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26854         printf "Seeking data from 3000000 ... "
26855         offset=$(lseek_test -d 3000000 $file)
26856         echo $offset
26857         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26858
26859         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26860                 error "2nd dd fails"
26861         echo "Add data block at 640K...1280K"
26862
26863         # start at before new data block, in hole
26864         printf "Seeking hole from 600000 ... "
26865         offset=$(lseek_test -l 600000 $file)
26866         echo $offset
26867         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26868         printf "Seeking data from 600000 ... "
26869         offset=$(lseek_test -d 600000 $file)
26870         echo $offset
26871         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26872
26873         # start at the first component new data block
26874         printf "Seeking hole from 1000000 ... "
26875         offset=$(lseek_test -l 1000000 $file)
26876         echo $offset
26877         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26878         printf "Seeking data from 1000000 ... "
26879         offset=$(lseek_test -d 1000000 $file)
26880         echo $offset
26881         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26882
26883         # start at second component stripe 2, new data
26884         printf "Seeking hole from 1200000 ... "
26885         offset=$(lseek_test -l 1200000 $file)
26886         echo $offset
26887         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26888         printf "Seeking data from 1200000 ... "
26889         offset=$(lseek_test -d 1200000 $file)
26890         echo $offset
26891         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26892
26893         # start beyond file end
26894         printf "Using offset > filesize ... "
26895         lseek_test -l 4000000 $file && error "lseek should fail"
26896         printf "Using offset > filesize ... "
26897         lseek_test -d 4000000 $file && error "lseek should fail"
26898
26899         printf "Done\n\n"
26900 }
26901
26902 test_430a() {
26903         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26904                 skip "MDT does not support SEEK_HOLE"
26905
26906         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26907                 skip "OST does not support SEEK_HOLE"
26908
26909         local file=$DIR/$tdir/$tfile
26910
26911         mkdir -p $DIR/$tdir
26912
26913         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26914         # OST stripe #1 will have continuous data at [1M, 3M)
26915         # OST stripe #2 is empty
26916         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26917         lseek_test_430 $file
26918         rm $file
26919         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26920         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26921         lseek_test_430 $file
26922         rm $file
26923         $LFS setstripe -c2 -S 512K $file
26924         echo "Two stripes, stripe size 512K"
26925         lseek_test_430 $file
26926         rm $file
26927         # FLR with stale mirror
26928         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26929                        -N -c2 -S 1M $file
26930         echo "Mirrored file:"
26931         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26932         echo "Plain 2 stripes 1M"
26933         lseek_test_430 $file
26934         rm $file
26935 }
26936 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26937
26938 test_430b() {
26939         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26940                 skip "OST does not support SEEK_HOLE"
26941
26942         local offset
26943         local file=$DIR/$tdir/$tfile
26944
26945         mkdir -p $DIR/$tdir
26946         # Empty layout lseek should fail
26947         $MCREATE $file
26948         # seek from 0
26949         printf "Seeking hole from 0 ... "
26950         lseek_test -l 0 $file && error "lseek should fail"
26951         printf "Seeking data from 0 ... "
26952         lseek_test -d 0 $file && error "lseek should fail"
26953         rm $file
26954
26955         # 1M-hole file
26956         $LFS setstripe -E 1M -c2 -E eof $file
26957         $TRUNCATE $file 1048576
26958         printf "Seeking hole from 1000000 ... "
26959         offset=$(lseek_test -l 1000000 $file)
26960         echo $offset
26961         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26962         printf "Seeking data from 1000000 ... "
26963         lseek_test -d 1000000 $file && error "lseek should fail"
26964         rm $file
26965
26966         # full component followed by non-inited one
26967         $LFS setstripe -E 1M -c2 -E eof $file
26968         dd if=/dev/urandom of=$file bs=1M count=1
26969         printf "Seeking hole from 1000000 ... "
26970         offset=$(lseek_test -l 1000000 $file)
26971         echo $offset
26972         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26973         printf "Seeking hole from 1048576 ... "
26974         lseek_test -l 1048576 $file && error "lseek should fail"
26975         # init second component and truncate back
26976         echo "123" >> $file
26977         $TRUNCATE $file 1048576
26978         printf "Seeking hole from 1000000 ... "
26979         offset=$(lseek_test -l 1000000 $file)
26980         echo $offset
26981         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26982         printf "Seeking hole from 1048576 ... "
26983         lseek_test -l 1048576 $file && error "lseek should fail"
26984         # boundary checks for big values
26985         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26986         offset=$(lseek_test -d 0 $file.10g)
26987         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26988         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26989         offset=$(lseek_test -d 0 $file.100g)
26990         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26991         return 0
26992 }
26993 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26994
26995 test_430c() {
26996         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26997                 skip "OST does not support SEEK_HOLE"
26998
26999         local file=$DIR/$tdir/$tfile
27000         local start
27001
27002         mkdir -p $DIR/$tdir
27003         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27004
27005         # cp version 8.33+ prefers lseek over fiemap
27006         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27007                 start=$SECONDS
27008                 time cp $file /dev/null
27009                 (( SECONDS - start < 5 )) ||
27010                         error "cp: too long runtime $((SECONDS - start))"
27011
27012         fi
27013         # tar version 1.29+ supports SEEK_HOLE/DATA
27014         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27015                 start=$SECONDS
27016                 time tar cS $file - | cat > /dev/null
27017                 (( SECONDS - start < 5 )) ||
27018                         error "tar: too long runtime $((SECONDS - start))"
27019         fi
27020 }
27021 run_test 430c "lseek: external tools check"
27022
27023 test_431() { # LU-14187
27024         local file=$DIR/$tdir/$tfile
27025
27026         mkdir -p $DIR/$tdir
27027         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27028         dd if=/dev/urandom of=$file bs=4k count=1
27029         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27030         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27031         #define OBD_FAIL_OST_RESTART_IO 0x251
27032         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27033         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27034         cp $file $file.0
27035         cancel_lru_locks
27036         sync_all_data
27037         echo 3 > /proc/sys/vm/drop_caches
27038         diff  $file $file.0 || error "data diff"
27039 }
27040 run_test 431 "Restart transaction for IO"
27041
27042 cleanup_test_432() {
27043         do_facet mgs $LCTL nodemap_activate 0
27044         wait_nm_sync active
27045 }
27046
27047 test_432() {
27048         local tmpdir=$TMP/dir432
27049
27050         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27051                 skip "Need MDS version at least 2.14.52"
27052
27053         stack_trap cleanup_test_432 EXIT
27054         mkdir $DIR/$tdir
27055         mkdir $tmpdir
27056
27057         do_facet mgs $LCTL nodemap_activate 1
27058         wait_nm_sync active
27059         do_facet mgs $LCTL nodemap_modify --name default \
27060                 --property admin --value 1
27061         do_facet mgs $LCTL nodemap_modify --name default \
27062                 --property trusted --value 1
27063         cancel_lru_locks mdc
27064         wait_nm_sync default admin_nodemap
27065         wait_nm_sync default trusted_nodemap
27066
27067         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27068                grep -ci "Operation not permitted") -ne 0 ]; then
27069                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27070         fi
27071 }
27072 run_test 432 "mv dir from outside Lustre"
27073
27074 test_433() {
27075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27076
27077         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27078                 skip "inode cache not supported"
27079
27080         $LCTL set_param llite.*.inode_cache=0
27081         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27082
27083         local count=256
27084         local before
27085         local after
27086
27087         cancel_lru_locks mdc
27088         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27089         createmany -m $DIR/$tdir/f $count
27090         createmany -d $DIR/$tdir/d $count
27091         ls -l $DIR/$tdir > /dev/null
27092         stack_trap "rm -rf $DIR/$tdir"
27093
27094         before=$(num_objects)
27095         cancel_lru_locks mdc
27096         after=$(num_objects)
27097
27098         # sometimes even @before is less than 2 * count
27099         while (( before - after < count )); do
27100                 sleep 1
27101                 after=$(num_objects)
27102                 wait=$((wait + 1))
27103                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27104                 if (( wait > 60 )); then
27105                         error "inode slab grew from $before to $after"
27106                 fi
27107         done
27108
27109         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27110 }
27111 run_test 433 "ldlm lock cancel releases dentries and inodes"
27112
27113 prep_801() {
27114         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27115         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27116                 skip "Need server version at least 2.9.55"
27117
27118         start_full_debug_logging
27119 }
27120
27121 post_801() {
27122         stop_full_debug_logging
27123 }
27124
27125 barrier_stat() {
27126         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27127                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27128                            awk '/The barrier for/ { print $7 }')
27129                 echo $st
27130         else
27131                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27132                 echo \'$st\'
27133         fi
27134 }
27135
27136 barrier_expired() {
27137         local expired
27138
27139         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27140                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27141                           awk '/will be expired/ { print $7 }')
27142         else
27143                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27144         fi
27145
27146         echo $expired
27147 }
27148
27149 test_801a() {
27150         prep_801
27151
27152         echo "Start barrier_freeze at: $(date)"
27153         #define OBD_FAIL_BARRIER_DELAY          0x2202
27154         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27155         # Do not reduce barrier time - See LU-11873
27156         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27157
27158         sleep 2
27159         local b_status=$(barrier_stat)
27160         echo "Got barrier status at: $(date)"
27161         [ "$b_status" = "'freezing_p1'" ] ||
27162                 error "(1) unexpected barrier status $b_status"
27163
27164         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27165         wait
27166         b_status=$(barrier_stat)
27167         [ "$b_status" = "'frozen'" ] ||
27168                 error "(2) unexpected barrier status $b_status"
27169
27170         local expired=$(barrier_expired)
27171         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27172         sleep $((expired + 3))
27173
27174         b_status=$(barrier_stat)
27175         [ "$b_status" = "'expired'" ] ||
27176                 error "(3) unexpected barrier status $b_status"
27177
27178         # Do not reduce barrier time - See LU-11873
27179         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27180                 error "(4) fail to freeze barrier"
27181
27182         b_status=$(barrier_stat)
27183         [ "$b_status" = "'frozen'" ] ||
27184                 error "(5) unexpected barrier status $b_status"
27185
27186         echo "Start barrier_thaw at: $(date)"
27187         #define OBD_FAIL_BARRIER_DELAY          0x2202
27188         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27189         do_facet mgs $LCTL barrier_thaw $FSNAME &
27190
27191         sleep 2
27192         b_status=$(barrier_stat)
27193         echo "Got barrier status at: $(date)"
27194         [ "$b_status" = "'thawing'" ] ||
27195                 error "(6) unexpected barrier status $b_status"
27196
27197         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27198         wait
27199         b_status=$(barrier_stat)
27200         [ "$b_status" = "'thawed'" ] ||
27201                 error "(7) unexpected barrier status $b_status"
27202
27203         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27204         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27205         do_facet mgs $LCTL barrier_freeze $FSNAME
27206
27207         b_status=$(barrier_stat)
27208         [ "$b_status" = "'failed'" ] ||
27209                 error "(8) unexpected barrier status $b_status"
27210
27211         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27212         do_facet mgs $LCTL barrier_thaw $FSNAME
27213
27214         post_801
27215 }
27216 run_test 801a "write barrier user interfaces and stat machine"
27217
27218 test_801b() {
27219         prep_801
27220
27221         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27222         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27223         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27224         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27225         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27226
27227         cancel_lru_locks mdc
27228
27229         # 180 seconds should be long enough
27230         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27231
27232         local b_status=$(barrier_stat)
27233         [ "$b_status" = "'frozen'" ] ||
27234                 error "(6) unexpected barrier status $b_status"
27235
27236         mkdir $DIR/$tdir/d0/d10 &
27237         mkdir_pid=$!
27238
27239         touch $DIR/$tdir/d1/f13 &
27240         touch_pid=$!
27241
27242         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27243         ln_pid=$!
27244
27245         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27246         mv_pid=$!
27247
27248         rm -f $DIR/$tdir/d4/f12 &
27249         rm_pid=$!
27250
27251         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27252
27253         # To guarantee taht the 'stat' is not blocked
27254         b_status=$(barrier_stat)
27255         [ "$b_status" = "'frozen'" ] ||
27256                 error "(8) unexpected barrier status $b_status"
27257
27258         # let above commands to run at background
27259         sleep 5
27260
27261         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27262         ps -p $touch_pid || error "(10) touch should be blocked"
27263         ps -p $ln_pid || error "(11) link should be blocked"
27264         ps -p $mv_pid || error "(12) rename should be blocked"
27265         ps -p $rm_pid || error "(13) unlink should be blocked"
27266
27267         b_status=$(barrier_stat)
27268         [ "$b_status" = "'frozen'" ] ||
27269                 error "(14) unexpected barrier status $b_status"
27270
27271         do_facet mgs $LCTL barrier_thaw $FSNAME
27272         b_status=$(barrier_stat)
27273         [ "$b_status" = "'thawed'" ] ||
27274                 error "(15) unexpected barrier status $b_status"
27275
27276         wait $mkdir_pid || error "(16) mkdir should succeed"
27277         wait $touch_pid || error "(17) touch should succeed"
27278         wait $ln_pid || error "(18) link should succeed"
27279         wait $mv_pid || error "(19) rename should succeed"
27280         wait $rm_pid || error "(20) unlink should succeed"
27281
27282         post_801
27283 }
27284 run_test 801b "modification will be blocked by write barrier"
27285
27286 test_801c() {
27287         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27288
27289         prep_801
27290
27291         stop mds2 || error "(1) Fail to stop mds2"
27292
27293         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27294
27295         local b_status=$(barrier_stat)
27296         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27297                 do_facet mgs $LCTL barrier_thaw $FSNAME
27298                 error "(2) unexpected barrier status $b_status"
27299         }
27300
27301         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27302                 error "(3) Fail to rescan barrier bitmap"
27303
27304         # Do not reduce barrier time - See LU-11873
27305         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27306
27307         b_status=$(barrier_stat)
27308         [ "$b_status" = "'frozen'" ] ||
27309                 error "(4) unexpected barrier status $b_status"
27310
27311         do_facet mgs $LCTL barrier_thaw $FSNAME
27312         b_status=$(barrier_stat)
27313         [ "$b_status" = "'thawed'" ] ||
27314                 error "(5) unexpected barrier status $b_status"
27315
27316         local devname=$(mdsdevname 2)
27317
27318         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27319
27320         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27321                 error "(7) Fail to rescan barrier bitmap"
27322
27323         post_801
27324 }
27325 run_test 801c "rescan barrier bitmap"
27326
27327 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27328 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27329 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27330 saved_MOUNT_OPTS=$MOUNT_OPTS
27331
27332 cleanup_802a() {
27333         trap 0
27334
27335         stopall
27336         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27337         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27338         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27339         MOUNT_OPTS=$saved_MOUNT_OPTS
27340         setupall
27341 }
27342
27343 test_802a() {
27344         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27345         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27346         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27347                 skip "Need server version at least 2.9.55"
27348
27349         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27350
27351         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27352
27353         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27354                 error "(2) Fail to copy"
27355
27356         trap cleanup_802a EXIT
27357
27358         # sync by force before remount as readonly
27359         sync; sync_all_data; sleep 3; sync_all_data
27360
27361         stopall
27362
27363         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27364         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27365         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27366
27367         echo "Mount the server as read only"
27368         setupall server_only || error "(3) Fail to start servers"
27369
27370         echo "Mount client without ro should fail"
27371         mount_client $MOUNT &&
27372                 error "(4) Mount client without 'ro' should fail"
27373
27374         echo "Mount client with ro should succeed"
27375         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27376         mount_client $MOUNT ||
27377                 error "(5) Mount client with 'ro' should succeed"
27378
27379         echo "Modify should be refused"
27380         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27381
27382         echo "Read should be allowed"
27383         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27384                 error "(7) Read should succeed under ro mode"
27385
27386         cleanup_802a
27387 }
27388 run_test 802a "simulate readonly device"
27389
27390 test_802b() {
27391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27392         remote_mds_nodsh && skip "remote MDS with nodsh"
27393
27394         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27395                 skip "readonly option not available"
27396
27397         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27398
27399         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27400                 error "(2) Fail to copy"
27401
27402         # write back all cached data before setting MDT to readonly
27403         cancel_lru_locks
27404         sync_all_data
27405
27406         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27407         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
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         # disable readonly
27417         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27418 }
27419 run_test 802b "be able to set MDTs to readonly"
27420
27421 test_803a() {
27422         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27423         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27424                 skip "MDS needs to be newer than 2.10.54"
27425
27426         mkdir_on_mdt0 $DIR/$tdir
27427         # Create some objects on all MDTs to trigger related logs objects
27428         for idx in $(seq $MDSCOUNT); do
27429                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27430                         $DIR/$tdir/dir${idx} ||
27431                         error "Fail to create $DIR/$tdir/dir${idx}"
27432         done
27433
27434         sync; sleep 3
27435         wait_delete_completed # ensure old test cleanups are finished
27436         echo "before create:"
27437         $LFS df -i $MOUNT
27438         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27439
27440         for i in {1..10}; do
27441                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27442                         error "Fail to create $DIR/$tdir/foo$i"
27443         done
27444
27445         sync; sleep 3
27446         echo "after create:"
27447         $LFS df -i $MOUNT
27448         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27449
27450         # allow for an llog to be cleaned up during the test
27451         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27452                 error "before ($before_used) + 10 > after ($after_used)"
27453
27454         for i in {1..10}; do
27455                 rm -rf $DIR/$tdir/foo$i ||
27456                         error "Fail to remove $DIR/$tdir/foo$i"
27457         done
27458
27459         sleep 3 # avoid MDT return cached statfs
27460         wait_delete_completed
27461         echo "after unlink:"
27462         $LFS df -i $MOUNT
27463         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27464
27465         # allow for an llog to be created during the test
27466         [ $after_used -le $((before_used + 1)) ] ||
27467                 error "after ($after_used) > before ($before_used) + 1"
27468 }
27469 run_test 803a "verify agent object for remote object"
27470
27471 test_803b() {
27472         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27473         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27474                 skip "MDS needs to be newer than 2.13.56"
27475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27476
27477         for i in $(seq 0 $((MDSCOUNT - 1))); do
27478                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27479         done
27480
27481         local before=0
27482         local after=0
27483
27484         local tmp
27485
27486         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27487         for i in $(seq 0 $((MDSCOUNT - 1))); do
27488                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27489                         awk '/getattr/ { print $2 }')
27490                 before=$((before + tmp))
27491         done
27492         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27493         for i in $(seq 0 $((MDSCOUNT - 1))); do
27494                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27495                         awk '/getattr/ { print $2 }')
27496                 after=$((after + tmp))
27497         done
27498
27499         [ $before -eq $after ] || error "getattr count $before != $after"
27500 }
27501 run_test 803b "remote object can getattr from cache"
27502
27503 test_804() {
27504         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27505         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27506                 skip "MDS needs to be newer than 2.10.54"
27507         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27508
27509         mkdir -p $DIR/$tdir
27510         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27511                 error "Fail to create $DIR/$tdir/dir0"
27512
27513         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27514         local dev=$(mdsdevname 2)
27515
27516         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27517                 grep ${fid} || error "NOT found agent entry for dir0"
27518
27519         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27520                 error "Fail to create $DIR/$tdir/dir1"
27521
27522         touch $DIR/$tdir/dir1/foo0 ||
27523                 error "Fail to create $DIR/$tdir/dir1/foo0"
27524         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27525         local rc=0
27526
27527         for idx in $(seq $MDSCOUNT); do
27528                 dev=$(mdsdevname $idx)
27529                 do_facet mds${idx} \
27530                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27531                         grep ${fid} && rc=$idx
27532         done
27533
27534         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27535                 error "Fail to rename foo0 to foo1"
27536         if [ $rc -eq 0 ]; then
27537                 for idx in $(seq $MDSCOUNT); do
27538                         dev=$(mdsdevname $idx)
27539                         do_facet mds${idx} \
27540                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27541                         grep ${fid} && rc=$idx
27542                 done
27543         fi
27544
27545         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27546                 error "Fail to rename foo1 to foo2"
27547         if [ $rc -eq 0 ]; then
27548                 for idx in $(seq $MDSCOUNT); do
27549                         dev=$(mdsdevname $idx)
27550                         do_facet mds${idx} \
27551                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27552                         grep ${fid} && rc=$idx
27553                 done
27554         fi
27555
27556         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27557
27558         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27559                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27560         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27561                 error "Fail to rename foo2 to foo0"
27562         unlink $DIR/$tdir/dir1/foo0 ||
27563                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27564         rm -rf $DIR/$tdir/dir0 ||
27565                 error "Fail to rm $DIR/$tdir/dir0"
27566
27567         for idx in $(seq $MDSCOUNT); do
27568                 rc=0
27569
27570                 stop mds${idx}
27571                 dev=$(mdsdevname $idx)
27572                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27573                         rc=$?
27574                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27575                         error "mount mds$idx failed"
27576                 df $MOUNT > /dev/null 2>&1
27577
27578                 # e2fsck should not return error
27579                 [ $rc -eq 0 ] ||
27580                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27581         done
27582 }
27583 run_test 804 "verify agent entry for remote entry"
27584
27585 cleanup_805() {
27586         do_facet $SINGLEMDS zfs set quota=$old $fsset
27587         unlinkmany $DIR/$tdir/f- 1000000
27588         trap 0
27589 }
27590
27591 test_805() {
27592         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27593         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27594         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27595                 skip "netfree not implemented before 0.7"
27596         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27597                 skip "Need MDS version at least 2.10.57"
27598
27599         local fsset
27600         local freekb
27601         local usedkb
27602         local old
27603         local quota
27604         local pref="osd-zfs.$FSNAME-MDT0000."
27605
27606         # limit available space on MDS dataset to meet nospace issue
27607         # quickly. then ZFS 0.7.2 can use reserved space if asked
27608         # properly (using netfree flag in osd_declare_destroy()
27609         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27610         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27611                 gawk '{print $3}')
27612         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27613         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27614         let "usedkb=usedkb-freekb"
27615         let "freekb=freekb/2"
27616         if let "freekb > 5000"; then
27617                 let "freekb=5000"
27618         fi
27619         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27620         trap cleanup_805 EXIT
27621         mkdir_on_mdt0 $DIR/$tdir
27622         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27623                 error "Can't set PFL layout"
27624         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27625         rm -rf $DIR/$tdir || error "not able to remove"
27626         do_facet $SINGLEMDS zfs set quota=$old $fsset
27627         trap 0
27628 }
27629 run_test 805 "ZFS can remove from full fs"
27630
27631 # Size-on-MDS test
27632 check_lsom_data()
27633 {
27634         local file=$1
27635         local expect=$(stat -c %s $file)
27636
27637         check_lsom_size $1 $expect
27638
27639         local blocks=$($LFS getsom -b $file)
27640         expect=$(stat -c %b $file)
27641         [[ $blocks == $expect ]] ||
27642                 error "$file expected blocks: $expect, got: $blocks"
27643 }
27644
27645 check_lsom_size()
27646 {
27647         local size
27648         local expect=$2
27649
27650         cancel_lru_locks mdc
27651
27652         size=$($LFS getsom -s $1)
27653         [[ $size == $expect ]] ||
27654                 error "$file expected size: $expect, got: $size"
27655 }
27656
27657 test_806() {
27658         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27659                 skip "Need MDS version at least 2.11.52"
27660
27661         local bs=1048576
27662
27663         touch $DIR/$tfile || error "touch $tfile failed"
27664
27665         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27666         save_lustre_params client "llite.*.xattr_cache" > $save
27667         lctl set_param llite.*.xattr_cache=0
27668         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27669
27670         # single-threaded write
27671         echo "Test SOM for single-threaded write"
27672         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27673                 error "write $tfile failed"
27674         check_lsom_size $DIR/$tfile $bs
27675
27676         local num=32
27677         local size=$(($num * $bs))
27678         local offset=0
27679         local i
27680
27681         echo "Test SOM for single client multi-threaded($num) write"
27682         $TRUNCATE $DIR/$tfile 0
27683         for ((i = 0; i < $num; i++)); do
27684                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27685                 local pids[$i]=$!
27686                 offset=$((offset + $bs))
27687         done
27688         for (( i=0; i < $num; i++ )); do
27689                 wait ${pids[$i]}
27690         done
27691         check_lsom_size $DIR/$tfile $size
27692
27693         $TRUNCATE $DIR/$tfile 0
27694         for ((i = 0; i < $num; i++)); do
27695                 offset=$((offset - $bs))
27696                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27697                 local pids[$i]=$!
27698         done
27699         for (( i=0; i < $num; i++ )); do
27700                 wait ${pids[$i]}
27701         done
27702         check_lsom_size $DIR/$tfile $size
27703
27704         # multi-client writes
27705         num=$(get_node_count ${CLIENTS//,/ })
27706         size=$(($num * $bs))
27707         offset=0
27708         i=0
27709
27710         echo "Test SOM for multi-client ($num) writes"
27711         $TRUNCATE $DIR/$tfile 0
27712         for client in ${CLIENTS//,/ }; do
27713                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27714                 local pids[$i]=$!
27715                 i=$((i + 1))
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 $offset
27722
27723         i=0
27724         $TRUNCATE $DIR/$tfile 0
27725         for client in ${CLIENTS//,/ }; do
27726                 offset=$((offset - $bs))
27727                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27728                 local pids[$i]=$!
27729                 i=$((i + 1))
27730         done
27731         for (( i=0; i < $num; i++ )); do
27732                 wait ${pids[$i]}
27733         done
27734         check_lsom_size $DIR/$tfile $size
27735
27736         # verify truncate
27737         echo "Test SOM for truncate"
27738         $TRUNCATE $DIR/$tfile 1048576
27739         check_lsom_size $DIR/$tfile 1048576
27740         $TRUNCATE $DIR/$tfile 1234
27741         check_lsom_size $DIR/$tfile 1234
27742
27743         # verify SOM blocks count
27744         echo "Verify SOM block count"
27745         $TRUNCATE $DIR/$tfile 0
27746         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27747                 error "failed to write file $tfile"
27748         check_lsom_data $DIR/$tfile
27749 }
27750 run_test 806 "Verify Lazy Size on MDS"
27751
27752 test_807() {
27753         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27754         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27755                 skip "Need MDS version at least 2.11.52"
27756
27757         # Registration step
27758         changelog_register || error "changelog_register failed"
27759         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27760         changelog_users $SINGLEMDS | grep -q $cl_user ||
27761                 error "User $cl_user not found in changelog_users"
27762
27763         rm -rf $DIR/$tdir || error "rm $tdir failed"
27764         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27765         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27766         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27767         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27768                 error "truncate $tdir/trunc failed"
27769
27770         local bs=1048576
27771         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27772                 error "write $tfile failed"
27773
27774         # multi-client wirtes
27775         local num=$(get_node_count ${CLIENTS//,/ })
27776         local offset=0
27777         local i=0
27778
27779         echo "Test SOM for multi-client ($num) writes"
27780         touch $DIR/$tfile || error "touch $tfile failed"
27781         $TRUNCATE $DIR/$tfile 0
27782         for client in ${CLIENTS//,/ }; do
27783                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27784                 local pids[$i]=$!
27785                 i=$((i + 1))
27786                 offset=$((offset + $bs))
27787         done
27788         for (( i=0; i < $num; i++ )); do
27789                 wait ${pids[$i]}
27790         done
27791
27792         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27793         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27794         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27795         check_lsom_data $DIR/$tdir/trunc
27796         check_lsom_data $DIR/$tdir/single_dd
27797         check_lsom_data $DIR/$tfile
27798
27799         rm -rf $DIR/$tdir
27800         # Deregistration step
27801         changelog_deregister || error "changelog_deregister failed"
27802 }
27803 run_test 807 "verify LSOM syncing tool"
27804
27805 check_som_nologged()
27806 {
27807         local lines=$($LFS changelog $FSNAME-MDT0000 |
27808                 grep 'x=trusted.som' | wc -l)
27809         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27810 }
27811
27812 test_808() {
27813         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27814                 skip "Need MDS version at least 2.11.55"
27815
27816         # Registration step
27817         changelog_register || error "changelog_register failed"
27818
27819         touch $DIR/$tfile || error "touch $tfile failed"
27820         check_som_nologged
27821
27822         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27823                 error "write $tfile failed"
27824         check_som_nologged
27825
27826         $TRUNCATE $DIR/$tfile 1234
27827         check_som_nologged
27828
27829         $TRUNCATE $DIR/$tfile 1048576
27830         check_som_nologged
27831
27832         # Deregistration step
27833         changelog_deregister || error "changelog_deregister failed"
27834 }
27835 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27836
27837 check_som_nodata()
27838 {
27839         $LFS getsom $1
27840         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27841 }
27842
27843 test_809() {
27844         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27845                 skip "Need MDS version at least 2.11.56"
27846
27847         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27848                 error "failed to create DoM-only file $DIR/$tfile"
27849         touch $DIR/$tfile || error "touch $tfile failed"
27850         check_som_nodata $DIR/$tfile
27851
27852         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27853                 error "write $tfile failed"
27854         check_som_nodata $DIR/$tfile
27855
27856         $TRUNCATE $DIR/$tfile 1234
27857         check_som_nodata $DIR/$tfile
27858
27859         $TRUNCATE $DIR/$tfile 4097
27860         check_som_nodata $DIR/$file
27861 }
27862 run_test 809 "Verify no SOM xattr store for DoM-only files"
27863
27864 test_810() {
27865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27866         $GSS && skip_env "could not run with gss"
27867         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27868                 skip "OST < 2.12.58 doesn't align checksum"
27869
27870         set_checksums 1
27871         stack_trap "set_checksums $ORIG_CSUM" EXIT
27872         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27873
27874         local csum
27875         local before
27876         local after
27877         for csum in $CKSUM_TYPES; do
27878                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27879                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27880                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27881                         eval set -- $i
27882                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27883                         before=$(md5sum $DIR/$tfile)
27884                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27885                         after=$(md5sum $DIR/$tfile)
27886                         [ "$before" == "$after" ] ||
27887                                 error "$csum: $before != $after bs=$1 seek=$2"
27888                 done
27889         done
27890 }
27891 run_test 810 "partial page writes on ZFS (LU-11663)"
27892
27893 test_812a() {
27894         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27895                 skip "OST < 2.12.51 doesn't support this fail_loc"
27896
27897         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27898         # ensure ost1 is connected
27899         stat $DIR/$tfile >/dev/null || error "can't stat"
27900         wait_osc_import_state client ost1 FULL
27901         # no locks, no reqs to let the connection idle
27902         cancel_lru_locks osc
27903
27904         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27905 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27906         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27907         wait_osc_import_state client ost1 CONNECTING
27908         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27909
27910         stat $DIR/$tfile >/dev/null || error "can't stat file"
27911 }
27912 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27913
27914 test_812b() { # LU-12378
27915         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27916                 skip "OST < 2.12.51 doesn't support this fail_loc"
27917
27918         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27919         # ensure ost1 is connected
27920         stat $DIR/$tfile >/dev/null || error "can't stat"
27921         wait_osc_import_state client ost1 FULL
27922         # no locks, no reqs to let the connection idle
27923         cancel_lru_locks osc
27924
27925         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27926 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27927         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27928         wait_osc_import_state client ost1 CONNECTING
27929         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27930
27931         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27932         wait_osc_import_state client ost1 IDLE
27933 }
27934 run_test 812b "do not drop no resend request for idle connect"
27935
27936 test_812c() {
27937         local old
27938
27939         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27940
27941         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27942         $LFS getstripe $DIR/$tfile
27943         $LCTL set_param osc.*.idle_timeout=10
27944         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27945         # ensure ost1 is connected
27946         stat $DIR/$tfile >/dev/null || error "can't stat"
27947         wait_osc_import_state client ost1 FULL
27948         # no locks, no reqs to let the connection idle
27949         cancel_lru_locks osc
27950
27951 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27952         $LCTL set_param fail_loc=0x80000533
27953         sleep 15
27954         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27955 }
27956 run_test 812c "idle import vs lock enqueue race"
27957
27958 test_813() {
27959         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27960         [ -z "$file_heat_sav" ] && skip "no file heat support"
27961
27962         local readsample
27963         local writesample
27964         local readbyte
27965         local writebyte
27966         local readsample1
27967         local writesample1
27968         local readbyte1
27969         local writebyte1
27970
27971         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27972         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27973
27974         $LCTL set_param -n llite.*.file_heat=1
27975         echo "Turn on file heat"
27976         echo "Period second: $period_second, Decay percentage: $decay_pct"
27977
27978         echo "QQQQ" > $DIR/$tfile
27979         echo "QQQQ" > $DIR/$tfile
27980         echo "QQQQ" > $DIR/$tfile
27981         cat $DIR/$tfile > /dev/null
27982         cat $DIR/$tfile > /dev/null
27983         cat $DIR/$tfile > /dev/null
27984         cat $DIR/$tfile > /dev/null
27985
27986         local out=$($LFS heat_get $DIR/$tfile)
27987
27988         $LFS heat_get $DIR/$tfile
27989         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27990         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27991         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27992         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27993
27994         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27995         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27996         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27997         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27998
27999         sleep $((period_second + 3))
28000         echo "Sleep $((period_second + 3)) seconds..."
28001         # The recursion formula to calculate the heat of the file f is as
28002         # follow:
28003         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28004         # Where Hi is the heat value in the period between time points i*I and
28005         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28006         # to the weight of Ci.
28007         out=$($LFS heat_get $DIR/$tfile)
28008         $LFS heat_get $DIR/$tfile
28009         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28010         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28011         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28012         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28013
28014         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28015                 error "read sample ($readsample) is wrong"
28016         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28017                 error "write sample ($writesample) is wrong"
28018         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28019                 error "read bytes ($readbyte) is wrong"
28020         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28021                 error "write bytes ($writebyte) is wrong"
28022
28023         echo "QQQQ" > $DIR/$tfile
28024         echo "QQQQ" > $DIR/$tfile
28025         echo "QQQQ" > $DIR/$tfile
28026         cat $DIR/$tfile > /dev/null
28027         cat $DIR/$tfile > /dev/null
28028         cat $DIR/$tfile > /dev/null
28029         cat $DIR/$tfile > /dev/null
28030
28031         sleep $((period_second + 3))
28032         echo "Sleep $((period_second + 3)) seconds..."
28033
28034         out=$($LFS heat_get $DIR/$tfile)
28035         $LFS heat_get $DIR/$tfile
28036         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28037         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28038         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28039         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28040
28041         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28042                 4 * $decay_pct) / 100") -eq 1 ] ||
28043                 error "read sample ($readsample1) is wrong"
28044         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28045                 3 * $decay_pct) / 100") -eq 1 ] ||
28046                 error "write sample ($writesample1) is wrong"
28047         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28048                 20 * $decay_pct) / 100") -eq 1 ] ||
28049                 error "read bytes ($readbyte1) is wrong"
28050         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28051                 15 * $decay_pct) / 100") -eq 1 ] ||
28052                 error "write bytes ($writebyte1) is wrong"
28053
28054         echo "Turn off file heat for the file $DIR/$tfile"
28055         $LFS heat_set -o $DIR/$tfile
28056
28057         echo "QQQQ" > $DIR/$tfile
28058         echo "QQQQ" > $DIR/$tfile
28059         echo "QQQQ" > $DIR/$tfile
28060         cat $DIR/$tfile > /dev/null
28061         cat $DIR/$tfile > /dev/null
28062         cat $DIR/$tfile > /dev/null
28063         cat $DIR/$tfile > /dev/null
28064
28065         out=$($LFS heat_get $DIR/$tfile)
28066         $LFS heat_get $DIR/$tfile
28067         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28068         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28069         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28070         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28071
28072         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28073         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28074         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28075         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28076
28077         echo "Trun on file heat for the file $DIR/$tfile"
28078         $LFS heat_set -O $DIR/$tfile
28079
28080         echo "QQQQ" > $DIR/$tfile
28081         echo "QQQQ" > $DIR/$tfile
28082         echo "QQQQ" > $DIR/$tfile
28083         cat $DIR/$tfile > /dev/null
28084         cat $DIR/$tfile > /dev/null
28085         cat $DIR/$tfile > /dev/null
28086         cat $DIR/$tfile > /dev/null
28087
28088         out=$($LFS heat_get $DIR/$tfile)
28089         $LFS heat_get $DIR/$tfile
28090         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28091         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28092         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28093         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28094
28095         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28096         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28097         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28098         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28099
28100         $LFS heat_set -c $DIR/$tfile
28101         $LCTL set_param -n llite.*.file_heat=0
28102         echo "Turn off file heat support for the Lustre filesystem"
28103
28104         echo "QQQQ" > $DIR/$tfile
28105         echo "QQQQ" > $DIR/$tfile
28106         echo "QQQQ" > $DIR/$tfile
28107         cat $DIR/$tfile > /dev/null
28108         cat $DIR/$tfile > /dev/null
28109         cat $DIR/$tfile > /dev/null
28110         cat $DIR/$tfile > /dev/null
28111
28112         out=$($LFS heat_get $DIR/$tfile)
28113         $LFS heat_get $DIR/$tfile
28114         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28115         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28116         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28117         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28118
28119         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28120         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28121         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28122         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28123
28124         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28125         rm -f $DIR/$tfile
28126 }
28127 run_test 813 "File heat verfication"
28128
28129 test_814()
28130 {
28131         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28132         echo -n y >> $DIR/$tfile
28133         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28134         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28135 }
28136 run_test 814 "sparse cp works as expected (LU-12361)"
28137
28138 test_815()
28139 {
28140         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28141         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28142 }
28143 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28144
28145 test_816() {
28146         local ost1_imp=$(get_osc_import_name client ost1)
28147         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28148                          cut -d'.' -f2)
28149
28150         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28151         # ensure ost1 is connected
28152
28153         stat $DIR/$tfile >/dev/null || error "can't stat"
28154         wait_osc_import_state client ost1 FULL
28155         # no locks, no reqs to let the connection idle
28156         cancel_lru_locks osc
28157         lru_resize_disable osc
28158         local before
28159         local now
28160         before=$($LCTL get_param -n \
28161                  ldlm.namespaces.$imp_name.lru_size)
28162
28163         wait_osc_import_state client ost1 IDLE
28164         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28165         now=$($LCTL get_param -n \
28166               ldlm.namespaces.$imp_name.lru_size)
28167         [ $before == $now ] || error "lru_size changed $before != $now"
28168 }
28169 run_test 816 "do not reset lru_resize on idle reconnect"
28170
28171 cleanup_817() {
28172         umount $tmpdir
28173         exportfs -u localhost:$DIR/nfsexp
28174         rm -rf $DIR/nfsexp
28175 }
28176
28177 test_817() {
28178         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28179
28180         mkdir -p $DIR/nfsexp
28181         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28182                 error "failed to export nfs"
28183
28184         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28185         stack_trap cleanup_817 EXIT
28186
28187         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28188                 error "failed to mount nfs to $tmpdir"
28189
28190         cp /bin/true $tmpdir
28191         $DIR/nfsexp/true || error "failed to execute 'true' command"
28192 }
28193 run_test 817 "nfsd won't cache write lock for exec file"
28194
28195 test_818() {
28196         test_mkdir -i0 -c1 $DIR/$tdir
28197         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28198         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28199         stop $SINGLEMDS
28200
28201         # restore osp-syn threads
28202         stack_trap "fail $SINGLEMDS"
28203
28204         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28205         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28206         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28207                 error "start $SINGLEMDS failed"
28208         rm -rf $DIR/$tdir
28209
28210         local testid=$(echo $TESTNAME | tr '_' ' ')
28211
28212         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28213                 grep "run LFSCK" || error "run LFSCK is not suggested"
28214 }
28215 run_test 818 "unlink with failed llog"
28216
28217 test_819a() {
28218         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28219         cancel_lru_locks osc
28220         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28221         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28222         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28223         rm -f $TDIR/$tfile
28224 }
28225 run_test 819a "too big niobuf in read"
28226
28227 test_819b() {
28228         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28229         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28230         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28231         cancel_lru_locks osc
28232         sleep 1
28233         rm -f $TDIR/$tfile
28234 }
28235 run_test 819b "too big niobuf in write"
28236
28237
28238 function test_820_start_ost() {
28239         sleep 5
28240
28241         for num in $(seq $OSTCOUNT); do
28242                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28243         done
28244 }
28245
28246 test_820() {
28247         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28248
28249         mkdir $DIR/$tdir
28250         umount_client $MOUNT || error "umount failed"
28251         for num in $(seq $OSTCOUNT); do
28252                 stop ost$num
28253         done
28254
28255         # mount client with no active OSTs
28256         # so that the client can't initialize max LOV EA size
28257         # from OSC notifications
28258         mount_client $MOUNT || error "mount failed"
28259         # delay OST starting to keep this 0 max EA size for a while
28260         test_820_start_ost &
28261
28262         # create a directory on MDS2
28263         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28264                 error "Failed to create directory"
28265         # open intent should update default EA size
28266         # see mdc_update_max_ea_from_body()
28267         # notice this is the very first RPC to MDS2
28268         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28269         ret=$?
28270         echo $out
28271         # With SSK, this situation can lead to -EPERM being returned.
28272         # In that case, simply retry.
28273         if [ $ret -ne 0 ] && $SHARED_KEY; then
28274                 if echo "$out" | grep -q "not permitted"; then
28275                         cp /etc/services $DIR/$tdir/mds2
28276                         ret=$?
28277                 fi
28278         fi
28279         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28280 }
28281 run_test 820 "update max EA from open intent"
28282
28283 test_822() {
28284         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28285
28286         save_lustre_params mds1 \
28287                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28288         do_facet $SINGLEMDS "$LCTL set_param -n \
28289                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28290         do_facet $SINGLEMDS "$LCTL set_param -n \
28291                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28292
28293         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28294         local maxage=$(do_facet mds1 $LCTL get_param -n \
28295                        osp.$FSNAME-OST0000*MDT0000.maxage)
28296         sleep $((maxage + 1))
28297
28298         #define OBD_FAIL_NET_ERROR_RPC          0x532
28299         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28300
28301         stack_trap "restore_lustre_params < $p; rm $p"
28302
28303         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28304                       osp.$FSNAME-OST0000*MDT0000.create_count")
28305         for i in $(seq 1 $count); do
28306                 touch $DIR/$tfile.${i} || error "touch failed"
28307         done
28308 }
28309 run_test 822 "test precreate failure"
28310
28311 test_823() {
28312         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28313         local OST_MAX_PRECREATE=20000
28314
28315         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28316                 skip "Need MDS version at least 2.14.56"
28317
28318         save_lustre_params mds1 \
28319                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28320         do_facet $SINGLEMDS "$LCTL set_param -n \
28321                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28322         do_facet $SINGLEMDS "$LCTL set_param -n \
28323                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28324
28325         stack_trap "restore_lustre_params < $p; rm $p"
28326
28327         do_facet $SINGLEMDS "$LCTL set_param -n \
28328                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28329
28330         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28331                       osp.$FSNAME-OST0000*MDT0000.create_count")
28332         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28333                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28334         local expect_count=$(((($max/2)/256) * 256))
28335
28336         log "setting create_count to 100200:"
28337         log " -result- count: $count with max: $max, expecting: $expect_count"
28338
28339         [[ $count -eq expect_count ]] ||
28340                 error "Create count not set to max precreate."
28341 }
28342 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28343
28344 test_831() {
28345         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28346                 skip "Need MDS version 2.14.56"
28347
28348         local sync_changes=$(do_facet $SINGLEMDS \
28349                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28350
28351         [ "$sync_changes" -gt 100 ] &&
28352                 skip "Sync changes $sync_changes > 100 already"
28353
28354         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28355
28356         $LFS mkdir -i 0 $DIR/$tdir
28357         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28358
28359         save_lustre_params mds1 \
28360                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28361         save_lustre_params mds1 \
28362                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28363
28364         do_facet mds1 "$LCTL set_param -n \
28365                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28366                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28367         stack_trap "restore_lustre_params < $p" EXIT
28368
28369         createmany -o $DIR/$tdir/f- 1000
28370         unlinkmany $DIR/$tdir/f- 1000 &
28371         local UNLINK_PID=$!
28372
28373         while sleep 1; do
28374                 sync_changes=$(do_facet mds1 \
28375                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28376                 # the check in the code is racy, fail the test
28377                 # if the value above the limit by 10.
28378                 [ $sync_changes -gt 110 ] && {
28379                         kill -2 $UNLINK_PID
28380                         wait
28381                         error "osp changes throttling failed, $sync_changes>110"
28382                 }
28383                 kill -0 $UNLINK_PID 2> /dev/null || break
28384         done
28385         wait
28386 }
28387 run_test 831 "throttling unlink/setattr queuing on OSP"
28388
28389 #
28390 # tests that do cleanup/setup should be run at the end
28391 #
28392
28393 test_900() {
28394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28395         local ls
28396
28397         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28398         $LCTL set_param fail_loc=0x903
28399
28400         cancel_lru_locks MGC
28401
28402         FAIL_ON_ERROR=true cleanup
28403         FAIL_ON_ERROR=true setup
28404 }
28405 run_test 900 "umount should not race with any mgc requeue thread"
28406
28407 # LUS-6253/LU-11185
28408 test_901() {
28409         local old
28410         local count
28411         local oldc
28412         local newc
28413         local olds
28414         local news
28415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28416
28417         # some get_param have a bug to handle dot in param name
28418         cancel_lru_locks MGC
28419         old=$(mount -t lustre | wc -l)
28420         # 1 config+sptlrpc
28421         # 2 params
28422         # 3 nodemap
28423         # 4 IR
28424         old=$((old * 4))
28425         oldc=0
28426         count=0
28427         while [ $old -ne $oldc ]; do
28428                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28429                 sleep 1
28430                 ((count++))
28431                 if [ $count -ge $TIMEOUT ]; then
28432                         error "too large timeout"
28433                 fi
28434         done
28435         umount_client $MOUNT || error "umount failed"
28436         mount_client $MOUNT || error "mount failed"
28437         cancel_lru_locks MGC
28438         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28439
28440         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28441
28442         return 0
28443 }
28444 run_test 901 "don't leak a mgc lock on client umount"
28445
28446 # LU-13377
28447 test_902() {
28448         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28449                 skip "client does not have LU-13377 fix"
28450         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28451         $LCTL set_param fail_loc=0x1415
28452         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28453         cancel_lru_locks osc
28454         rm -f $DIR/$tfile
28455 }
28456 run_test 902 "test short write doesn't hang lustre"
28457
28458 # LU-14711
28459 test_903() {
28460         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28461         echo "blah" > $DIR/${tfile}-2
28462         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28463         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28464         $LCTL set_param fail_loc=0x417 fail_val=20
28465
28466         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28467         sleep 1 # To start the destroy
28468         wait_destroy_complete 150 || error "Destroy taking too long"
28469         cat $DIR/$tfile > /dev/null || error "Evicted"
28470 }
28471 run_test 903 "Test long page discard does not cause evictions"
28472
28473 test_904() {
28474         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28475         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28476                 grep -q project || skip "skip project quota not supported"
28477
28478         local testfile="$DIR/$tdir/$tfile"
28479         local xattr="trusted.projid"
28480         local projid
28481         local mdts=$(comma_list $(mdts_nodes))
28482         local saved=$(do_facet mds1 $LCTL get_param -n \
28483                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28484
28485         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28486         stack_trap "do_nodes $mdts $LCTL set_param \
28487                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28488
28489         mkdir -p $DIR/$tdir
28490         touch $testfile
28491         #hide projid xattr on server
28492         $LFS project -p 1 $testfile ||
28493                 error "set $testfile project id failed"
28494         getfattr -m - $testfile | grep $xattr &&
28495                 error "do not show trusted.projid when disabled on server"
28496         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28497         #should be hidden when projid is 0
28498         $LFS project -p 0 $testfile ||
28499                 error "set $testfile project id failed"
28500         getfattr -m - $testfile | grep $xattr &&
28501                 error "do not show trusted.projid with project ID 0"
28502
28503         #still can getxattr explicitly
28504         projid=$(getfattr -n $xattr $testfile |
28505                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28506         [ $projid == "0" ] ||
28507                 error "projid expected 0 not $projid"
28508
28509         #set the projid via setxattr
28510         setfattr -n $xattr -v "1000" $testfile ||
28511                 error "setattr failed with $?"
28512         projid=($($LFS project $testfile))
28513         [ ${projid[0]} == "1000" ] ||
28514                 error "projid expected 1000 not $projid"
28515
28516         #check the new projid via getxattr
28517         $LFS project -p 1001 $testfile ||
28518                 error "set $testfile project id failed"
28519         getfattr -m - $testfile | grep $xattr ||
28520                 error "should show trusted.projid when project ID != 0"
28521         projid=$(getfattr -n $xattr $testfile |
28522                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28523         [ $projid == "1001" ] ||
28524                 error "projid expected 1001 not $projid"
28525
28526         #try to set invalid projid
28527         setfattr -n $xattr -v "4294967295" $testfile &&
28528                 error "set invalid projid should fail"
28529
28530         #remove the xattr means setting projid to 0
28531         setfattr -x $xattr $testfile ||
28532                 error "setfattr failed with $?"
28533         projid=($($LFS project $testfile))
28534         [ ${projid[0]} == "0" ] ||
28535                 error "projid expected 0 not $projid"
28536
28537         #should be hidden when parent has inherit flag and same projid
28538         $LFS project -srp 1002 $DIR/$tdir ||
28539                 error "set $tdir project id failed"
28540         getfattr -m - $testfile | grep $xattr &&
28541                 error "do not show trusted.projid with inherit flag"
28542
28543         #still can getxattr explicitly
28544         projid=$(getfattr -n $xattr $testfile |
28545                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28546         [ $projid == "1002" ] ||
28547                 error "projid expected 1002 not $projid"
28548 }
28549 run_test 904 "virtual project ID xattr"
28550
28551 complete $SECONDS
28552 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28553 check_and_cleanup_lustre
28554 if [ "$I_MOUNTED" != "yes" ]; then
28555         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28556 fi
28557 exit_status