Whamcloud - gitweb
LU-15282 tests: relax test_51d thresholds somewhat
[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=6 # allow variance of (1 - $min/$max) = 33% by default
5896
5897         # For some combinations of stripecount and OSTCOUNT current code
5898         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5899         # than others. Rather than skipping this test entirely, check that
5900         # and keep testing to ensure imbalance does not get worse. LU-15282
5901         (( (OSTCOUNT == 6 && stripecount == 4) ||
5902            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5903            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5904         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5905                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5906                         { $LFS df && $LFS df -i &&
5907                         error "OST $n has fewer objects vs. OST $nlast " \
5908                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5909                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5910                         { $LFS df && $LFS df -i &&
5911                         error "OST $n has fewer objects vs. OST $nlast " \
5912                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5913
5914                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5915                         { $LFS df && $LFS df -i &&
5916                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5917                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5918                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5919                         { $LFS df && $LFS df -i &&
5920                         error "OST $n has fewer #0 objects vs. OST $nlast " \
5921                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5922         done
5923 }
5924
5925 test_51d() {
5926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5927         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5928
5929         local stripecount
5930         local qos_old=$(do_facet mds1 \
5931                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5932
5933         do_nodes $(comma_list $(mdts_nodes)) \
5934                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5935         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5936                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5937
5938         test_mkdir $DIR/$tdir
5939
5940         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5941                 test_51d_sub $stripecount
5942         done
5943 }
5944 run_test 51d "check object distribution"
5945
5946 test_51e() {
5947         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5948                 skip_env "ldiskfs only test"
5949         fi
5950
5951         test_mkdir -c1 $DIR/$tdir
5952         test_mkdir -c1 $DIR/$tdir/d0
5953
5954         touch $DIR/$tdir/d0/foo
5955         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5956                 error "file exceed 65000 nlink limit!"
5957         unlinkmany $DIR/$tdir/d0/f- 65001
5958         return 0
5959 }
5960 run_test 51e "check file nlink limit"
5961
5962 test_51f() {
5963         test_mkdir $DIR/$tdir
5964
5965         local max=100000
5966         local ulimit_old=$(ulimit -n)
5967         local spare=20 # number of spare fd's for scripts/libraries, etc.
5968         local mdt=$($LFS getstripe -m $DIR/$tdir)
5969         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5970
5971         echo "MDT$mdt numfree=$numfree, max=$max"
5972         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5973         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5974                 while ! ulimit -n $((numfree + spare)); do
5975                         numfree=$((numfree * 3 / 4))
5976                 done
5977                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5978         else
5979                 echo "left ulimit at $ulimit_old"
5980         fi
5981
5982         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5983                 unlinkmany $DIR/$tdir/f $numfree
5984                 error "create+open $numfree files in $DIR/$tdir failed"
5985         }
5986         ulimit -n $ulimit_old
5987
5988         # if createmany exits at 120s there will be fewer than $numfree files
5989         unlinkmany $DIR/$tdir/f $numfree || true
5990 }
5991 run_test 51f "check many open files limit"
5992
5993 test_52a() {
5994         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5995         test_mkdir $DIR/$tdir
5996         touch $DIR/$tdir/foo
5997         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5998         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5999         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6000         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6001         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6002                                         error "link worked"
6003         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6004         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6005         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6006                                                      error "lsattr"
6007         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6008         cp -r $DIR/$tdir $TMP/
6009         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6010 }
6011 run_test 52a "append-only flag test (should return errors)"
6012
6013 test_52b() {
6014         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6015         test_mkdir $DIR/$tdir
6016         touch $DIR/$tdir/foo
6017         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6018         cat test > $DIR/$tdir/foo && error "cat test worked"
6019         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6020         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6021         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6022                                         error "link worked"
6023         echo foo >> $DIR/$tdir/foo && error "echo worked"
6024         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6025         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6026         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6027         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6028                                                         error "lsattr"
6029         chattr -i $DIR/$tdir/foo || error "chattr failed"
6030
6031         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6032 }
6033 run_test 52b "immutable flag test (should return errors) ======="
6034
6035 test_53() {
6036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6037         remote_mds_nodsh && skip "remote MDS with nodsh"
6038         remote_ost_nodsh && skip "remote OST with nodsh"
6039
6040         local param
6041         local param_seq
6042         local ostname
6043         local mds_last
6044         local mds_last_seq
6045         local ost_last
6046         local ost_last_seq
6047         local ost_last_id
6048         local ostnum
6049         local node
6050         local found=false
6051         local support_last_seq=true
6052
6053         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6054                 support_last_seq=false
6055
6056         # only test MDT0000
6057         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6058         local value
6059         for value in $(do_facet $SINGLEMDS \
6060                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6061                 param=$(echo ${value[0]} | cut -d "=" -f1)
6062                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6063
6064                 if $support_last_seq; then
6065                         param_seq=$(echo $param |
6066                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6067                         mds_last_seq=$(do_facet $SINGLEMDS \
6068                                        $LCTL get_param -n $param_seq)
6069                 fi
6070                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6071
6072                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6073                 node=$(facet_active_host ost$((ostnum+1)))
6074                 param="obdfilter.$ostname.last_id"
6075                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6076                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6077                         ost_last_id=$ost_last
6078
6079                         if $support_last_seq; then
6080                                 ost_last_id=$(echo $ost_last |
6081                                               awk -F':' '{print $2}' |
6082                                               sed -e "s/^0x//g")
6083                                 ost_last_seq=$(echo $ost_last |
6084                                                awk -F':' '{print $1}')
6085                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6086                         fi
6087
6088                         if [[ $ost_last_id != $mds_last ]]; then
6089                                 error "$ost_last_id != $mds_last"
6090                         else
6091                                 found=true
6092                                 break
6093                         fi
6094                 done
6095         done
6096         $found || error "can not match last_seq/last_id for $mdtosc"
6097         return 0
6098 }
6099 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6100
6101 test_54a() {
6102         perl -MSocket -e ';' || skip "no Socket perl module installed"
6103
6104         $SOCKETSERVER $DIR/socket ||
6105                 error "$SOCKETSERVER $DIR/socket failed: $?"
6106         $SOCKETCLIENT $DIR/socket ||
6107                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6108         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6109 }
6110 run_test 54a "unix domain socket test =========================="
6111
6112 test_54b() {
6113         f="$DIR/f54b"
6114         mknod $f c 1 3
6115         chmod 0666 $f
6116         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6117 }
6118 run_test 54b "char device works in lustre ======================"
6119
6120 find_loop_dev() {
6121         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6122         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6123         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6124
6125         for i in $(seq 3 7); do
6126                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6127                 LOOPDEV=$LOOPBASE$i
6128                 LOOPNUM=$i
6129                 break
6130         done
6131 }
6132
6133 cleanup_54c() {
6134         local rc=0
6135         loopdev="$DIR/loop54c"
6136
6137         trap 0
6138         $UMOUNT $DIR/$tdir || rc=$?
6139         losetup -d $loopdev || true
6140         losetup -d $LOOPDEV || true
6141         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6142         return $rc
6143 }
6144
6145 test_54c() {
6146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6147
6148         loopdev="$DIR/loop54c"
6149
6150         find_loop_dev
6151         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6152         trap cleanup_54c EXIT
6153         mknod $loopdev b 7 $LOOPNUM
6154         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6155         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6156         losetup $loopdev $DIR/$tfile ||
6157                 error "can't set up $loopdev for $DIR/$tfile"
6158         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6159         test_mkdir $DIR/$tdir
6160         mount -t ext2 $loopdev $DIR/$tdir ||
6161                 error "error mounting $loopdev on $DIR/$tdir"
6162         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6163                 error "dd write"
6164         df $DIR/$tdir
6165         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6166                 error "dd read"
6167         cleanup_54c
6168 }
6169 run_test 54c "block device works in lustre ====================="
6170
6171 test_54d() {
6172         local pipe="$DIR/$tfile.pipe"
6173         local string="aaaaaa"
6174
6175         mknod $pipe p
6176         echo -n "$string" > $pipe &
6177         local result=$(cat $pipe)
6178         [[ "$result" == "$string" ]] || error "$result != $string"
6179 }
6180 run_test 54d "fifo device works in lustre ======================"
6181
6182 test_54e() {
6183         f="$DIR/f54e"
6184         string="aaaaaa"
6185         cp -aL /dev/console $f
6186         echo $string > $f || error "echo $string to $f failed"
6187 }
6188 run_test 54e "console/tty device works in lustre ======================"
6189
6190 test_56a() {
6191         local numfiles=3
6192         local numdirs=2
6193         local dir=$DIR/$tdir
6194
6195         rm -rf $dir
6196         test_mkdir -p $dir/dir
6197         for i in $(seq $numfiles); do
6198                 touch $dir/file$i
6199                 touch $dir/dir/file$i
6200         done
6201
6202         local numcomp=$($LFS getstripe --component-count $dir)
6203
6204         [[ $numcomp == 0 ]] && numcomp=1
6205
6206         # test lfs getstripe with --recursive
6207         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6208
6209         [[ $filenum -eq $((numfiles * 2)) ]] ||
6210                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6211         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6212         [[ $filenum -eq $numfiles ]] ||
6213                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6214         echo "$LFS getstripe showed obdidx or l_ost_idx"
6215
6216         # test lfs getstripe with file instead of dir
6217         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6218         [[ $filenum -eq 1 ]] ||
6219                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6220         echo "$LFS getstripe file1 passed"
6221
6222         #test lfs getstripe with --verbose
6223         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6224         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6225                 error "$LFS getstripe --verbose $dir: "\
6226                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6227         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6228                 error "$LFS getstripe $dir: showed lmm_magic"
6229
6230         #test lfs getstripe with -v prints lmm_fid
6231         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6232         local countfids=$((numdirs + numfiles * numcomp))
6233         [[ $filenum -eq $countfids ]] ||
6234                 error "$LFS getstripe -v $dir: "\
6235                       "got $filenum want $countfids lmm_fid"
6236         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6237                 error "$LFS getstripe $dir: showed lmm_fid by default"
6238         echo "$LFS getstripe --verbose passed"
6239
6240         #check for FID information
6241         local fid1=$($LFS getstripe --fid $dir/file1)
6242         local fid2=$($LFS getstripe --verbose $dir/file1 |
6243                      awk '/lmm_fid: / { print $2; exit; }')
6244         local fid3=$($LFS path2fid $dir/file1)
6245
6246         [ "$fid1" != "$fid2" ] &&
6247                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6248         [ "$fid1" != "$fid3" ] &&
6249                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6250         echo "$LFS getstripe --fid passed"
6251
6252         #test lfs getstripe with --obd
6253         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6254                 error "$LFS getstripe --obd wrong_uuid: should return error"
6255
6256         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6257
6258         local ostidx=1
6259         local obduuid=$(ostuuid_from_index $ostidx)
6260         local found=$($LFS getstripe -r --obd $obduuid $dir |
6261                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6262
6263         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6264         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6265                 ((filenum--))
6266         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6267                 ((filenum--))
6268
6269         [[ $found -eq $filenum ]] ||
6270                 error "$LFS getstripe --obd: found $found expect $filenum"
6271         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6272                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6273                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6274                 error "$LFS getstripe --obd: should not show file on other obd"
6275         echo "$LFS getstripe --obd passed"
6276 }
6277 run_test 56a "check $LFS getstripe"
6278
6279 test_56b() {
6280         local dir=$DIR/$tdir
6281         local numdirs=3
6282
6283         test_mkdir $dir
6284         for i in $(seq $numdirs); do
6285                 test_mkdir $dir/dir$i
6286         done
6287
6288         # test lfs getdirstripe default mode is non-recursion, which is
6289         # different from lfs getstripe
6290         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6291
6292         [[ $dircnt -eq 1 ]] ||
6293                 error "$LFS getdirstripe: found $dircnt, not 1"
6294         dircnt=$($LFS getdirstripe --recursive $dir |
6295                 grep -c lmv_stripe_count)
6296         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6297                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6298 }
6299 run_test 56b "check $LFS getdirstripe"
6300
6301 test_56c() {
6302         remote_ost_nodsh && skip "remote OST with nodsh"
6303
6304         local ost_idx=0
6305         local ost_name=$(ostname_from_index $ost_idx)
6306         local old_status=$(ost_dev_status $ost_idx)
6307         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6308
6309         [[ -z "$old_status" ]] ||
6310                 skip_env "OST $ost_name is in $old_status status"
6311
6312         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6313         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6314                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6315         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6316                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6317                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6318         fi
6319
6320         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6321                 error "$LFS df -v showing inactive devices"
6322         sleep_maxage
6323
6324         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6325
6326         [[ "$new_status" =~ "D" ]] ||
6327                 error "$ost_name status is '$new_status', missing 'D'"
6328         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6329                 [[ "$new_status" =~ "N" ]] ||
6330                         error "$ost_name status is '$new_status', missing 'N'"
6331         fi
6332         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6333                 [[ "$new_status" =~ "f" ]] ||
6334                         error "$ost_name status is '$new_status', missing 'f'"
6335         fi
6336
6337         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6338         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6339                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6340         [[ -z "$p" ]] && restore_lustre_params < $p || true
6341         sleep_maxage
6342
6343         new_status=$(ost_dev_status $ost_idx)
6344         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6345                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6346         # can't check 'f' as devices may actually be on flash
6347 }
6348 run_test 56c "check 'lfs df' showing device status"
6349
6350 test_56d() {
6351         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6352         local osts=$($LFS df -v $MOUNT | grep -c OST)
6353
6354         $LFS df $MOUNT
6355
6356         (( mdts == MDSCOUNT )) ||
6357                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6358         (( osts == OSTCOUNT )) ||
6359                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6360 }
6361 run_test 56d "'lfs df -v' prints only configured devices"
6362
6363 test_56e() {
6364         err_enoent=2 # No such file or directory
6365         err_eopnotsupp=95 # Operation not supported
6366
6367         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6368         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6369
6370         # Check for handling of path not exists
6371         output=$($LFS df $enoent_mnt 2>&1)
6372         ret=$?
6373
6374         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6375         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6376                 error "expect failure $err_enoent, not $ret"
6377
6378         # Check for handling of non-Lustre FS
6379         output=$($LFS df $notsup_mnt)
6380         ret=$?
6381
6382         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6383         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6384                 error "expect success $err_eopnotsupp, not $ret"
6385
6386         # Check for multiple LustreFS argument
6387         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6388         ret=$?
6389
6390         [[ $output -eq 3 && $ret -eq 0 ]] ||
6391                 error "expect success 3, not $output, rc = $ret"
6392
6393         # Check for correct non-Lustre FS handling among multiple
6394         # LustreFS argument
6395         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6396                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6397         ret=$?
6398
6399         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6400                 error "expect success 2, not $output, rc = $ret"
6401 }
6402 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6403
6404 NUMFILES=3
6405 NUMDIRS=3
6406 setup_56() {
6407         local local_tdir="$1"
6408         local local_numfiles="$2"
6409         local local_numdirs="$3"
6410         local dir_params="$4"
6411         local dir_stripe_params="$5"
6412
6413         if [ ! -d "$local_tdir" ] ; then
6414                 test_mkdir -p $dir_stripe_params $local_tdir
6415                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6416                 for i in $(seq $local_numfiles) ; do
6417                         touch $local_tdir/file$i
6418                 done
6419                 for i in $(seq $local_numdirs) ; do
6420                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6421                         for j in $(seq $local_numfiles) ; do
6422                                 touch $local_tdir/dir$i/file$j
6423                         done
6424                 done
6425         fi
6426 }
6427
6428 setup_56_special() {
6429         local local_tdir=$1
6430         local local_numfiles=$2
6431         local local_numdirs=$3
6432
6433         setup_56 $local_tdir $local_numfiles $local_numdirs
6434
6435         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6436                 for i in $(seq $local_numfiles) ; do
6437                         mknod $local_tdir/loop${i}b b 7 $i
6438                         mknod $local_tdir/null${i}c c 1 3
6439                         ln -s $local_tdir/file1 $local_tdir/link${i}
6440                 done
6441                 for i in $(seq $local_numdirs) ; do
6442                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6443                         mknod $local_tdir/dir$i/null${i}c c 1 3
6444                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6445                 done
6446         fi
6447 }
6448
6449 test_56g() {
6450         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6451         local expected=$(($NUMDIRS + 2))
6452
6453         setup_56 $dir $NUMFILES $NUMDIRS
6454
6455         # test lfs find with -name
6456         for i in $(seq $NUMFILES) ; do
6457                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6458
6459                 [ $nums -eq $expected ] ||
6460                         error "lfs find -name '*$i' $dir wrong: "\
6461                               "found $nums, expected $expected"
6462         done
6463 }
6464 run_test 56g "check lfs find -name"
6465
6466 test_56h() {
6467         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6468         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6469
6470         setup_56 $dir $NUMFILES $NUMDIRS
6471
6472         # test lfs find with ! -name
6473         for i in $(seq $NUMFILES) ; do
6474                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6475
6476                 [ $nums -eq $expected ] ||
6477                         error "lfs find ! -name '*$i' $dir wrong: "\
6478                               "found $nums, expected $expected"
6479         done
6480 }
6481 run_test 56h "check lfs find ! -name"
6482
6483 test_56i() {
6484         local dir=$DIR/$tdir
6485
6486         test_mkdir $dir
6487
6488         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6489         local out=$($cmd)
6490
6491         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6492 }
6493 run_test 56i "check 'lfs find -ost UUID' skips directories"
6494
6495 test_56j() {
6496         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6497
6498         setup_56_special $dir $NUMFILES $NUMDIRS
6499
6500         local expected=$((NUMDIRS + 1))
6501         local cmd="$LFS find -type d $dir"
6502         local nums=$($cmd | wc -l)
6503
6504         [ $nums -eq $expected ] ||
6505                 error "'$cmd' wrong: found $nums, expected $expected"
6506 }
6507 run_test 56j "check lfs find -type d"
6508
6509 test_56k() {
6510         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6511
6512         setup_56_special $dir $NUMFILES $NUMDIRS
6513
6514         local expected=$(((NUMDIRS + 1) * NUMFILES))
6515         local cmd="$LFS find -type f $dir"
6516         local nums=$($cmd | wc -l)
6517
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520 }
6521 run_test 56k "check lfs find -type f"
6522
6523 test_56l() {
6524         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6525
6526         setup_56_special $dir $NUMFILES $NUMDIRS
6527
6528         local expected=$((NUMDIRS + NUMFILES))
6529         local cmd="$LFS find -type b $dir"
6530         local nums=$($cmd | wc -l)
6531
6532         [ $nums -eq $expected ] ||
6533                 error "'$cmd' wrong: found $nums, expected $expected"
6534 }
6535 run_test 56l "check lfs find -type b"
6536
6537 test_56m() {
6538         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6539
6540         setup_56_special $dir $NUMFILES $NUMDIRS
6541
6542         local expected=$((NUMDIRS + NUMFILES))
6543         local cmd="$LFS find -type c $dir"
6544         local nums=$($cmd | wc -l)
6545         [ $nums -eq $expected ] ||
6546                 error "'$cmd' wrong: found $nums, expected $expected"
6547 }
6548 run_test 56m "check lfs find -type c"
6549
6550 test_56n() {
6551         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6552         setup_56_special $dir $NUMFILES $NUMDIRS
6553
6554         local expected=$((NUMDIRS + NUMFILES))
6555         local cmd="$LFS find -type l $dir"
6556         local nums=$($cmd | wc -l)
6557
6558         [ $nums -eq $expected ] ||
6559                 error "'$cmd' wrong: found $nums, expected $expected"
6560 }
6561 run_test 56n "check lfs find -type l"
6562
6563 test_56o() {
6564         local dir=$DIR/$tdir
6565
6566         setup_56 $dir $NUMFILES $NUMDIRS
6567         utime $dir/file1 > /dev/null || error "utime (1)"
6568         utime $dir/file2 > /dev/null || error "utime (2)"
6569         utime $dir/dir1 > /dev/null || error "utime (3)"
6570         utime $dir/dir2 > /dev/null || error "utime (4)"
6571         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6572         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6573
6574         local expected=4
6575         local nums=$($LFS find -mtime +0 $dir | wc -l)
6576
6577         [ $nums -eq $expected ] ||
6578                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6579
6580         expected=12
6581         cmd="$LFS find -mtime 0 $dir"
6582         nums=$($cmd | wc -l)
6583         [ $nums -eq $expected ] ||
6584                 error "'$cmd' wrong: found $nums, expected $expected"
6585 }
6586 run_test 56o "check lfs find -mtime for old files"
6587
6588 test_56ob() {
6589         local dir=$DIR/$tdir
6590         local expected=1
6591         local count=0
6592
6593         # just to make sure there is something that won't be found
6594         test_mkdir $dir
6595         touch $dir/$tfile.now
6596
6597         for age in year week day hour min; do
6598                 count=$((count + 1))
6599
6600                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6601                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6602                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6603
6604                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6605                 local nums=$($cmd | wc -l)
6606                 [ $nums -eq $expected ] ||
6607                         error "'$cmd' wrong: found $nums, expected $expected"
6608
6609                 cmd="$LFS find $dir -atime $count${age:0:1}"
6610                 nums=$($cmd | wc -l)
6611                 [ $nums -eq $expected ] ||
6612                         error "'$cmd' wrong: found $nums, expected $expected"
6613         done
6614
6615         sleep 2
6616         cmd="$LFS find $dir -ctime +1s -type f"
6617         nums=$($cmd | wc -l)
6618         (( $nums == $count * 2 + 1)) ||
6619                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6620 }
6621 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6622
6623 test_newerXY_base() {
6624         local x=$1
6625         local y=$2
6626         local dir=$DIR/$tdir
6627         local ref
6628         local negref
6629
6630         if [ $y == "t" ]; then
6631                 if [ $x == "b" ]; then
6632                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6633                 else
6634                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6635                 fi
6636         else
6637                 ref=$DIR/$tfile.newer.$x$y
6638                 touch $ref || error "touch $ref failed"
6639         fi
6640
6641         echo "before = $ref"
6642         sleep 2
6643         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6644         sleep 2
6645         if [ $y == "t" ]; then
6646                 if [ $x == "b" ]; then
6647                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6648                 else
6649                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6650                 fi
6651         else
6652                 negref=$DIR/$tfile.negnewer.$x$y
6653                 touch $negref || error "touch $negref failed"
6654         fi
6655
6656         echo "after = $negref"
6657         local cmd="$LFS find $dir -newer$x$y $ref"
6658         local nums=$(eval $cmd | wc -l)
6659         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6660
6661         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6662                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6663
6664         cmd="$LFS find $dir ! -newer$x$y $negref"
6665         nums=$(eval $cmd | wc -l)
6666         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6667                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6668
6669         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6670         nums=$(eval $cmd | wc -l)
6671         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6672                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6673
6674         rm -rf $DIR/*
6675 }
6676
6677 test_56oc() {
6678         test_newerXY_base "a" "a"
6679         test_newerXY_base "a" "m"
6680         test_newerXY_base "a" "c"
6681         test_newerXY_base "m" "a"
6682         test_newerXY_base "m" "m"
6683         test_newerXY_base "m" "c"
6684         test_newerXY_base "c" "a"
6685         test_newerXY_base "c" "m"
6686         test_newerXY_base "c" "c"
6687
6688         [[ -n "$sles_version" ]] &&
6689                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6690
6691         test_newerXY_base "a" "t"
6692         test_newerXY_base "m" "t"
6693         test_newerXY_base "c" "t"
6694
6695         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6696            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6697                 ! btime_supported && echo "btime unsupported" && return 0
6698
6699         test_newerXY_base "b" "b"
6700         test_newerXY_base "b" "t"
6701 }
6702 run_test 56oc "check lfs find -newerXY work"
6703
6704 btime_supported() {
6705         local dir=$DIR/$tdir
6706         local rc
6707
6708         mkdir -p $dir
6709         touch $dir/$tfile
6710         $LFS find $dir -btime -1d -type f
6711         rc=$?
6712         rm -rf $dir
6713         return $rc
6714 }
6715
6716 test_56od() {
6717         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6718                 ! btime_supported && skip "btime unsupported on MDS"
6719
6720         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6721                 ! btime_supported && skip "btime unsupported on clients"
6722
6723         local dir=$DIR/$tdir
6724         local ref=$DIR/$tfile.ref
6725         local negref=$DIR/$tfile.negref
6726
6727         mkdir $dir || error "mkdir $dir failed"
6728         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6729         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6730         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6731         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6732         touch $ref || error "touch $ref failed"
6733         # sleep 3 seconds at least
6734         sleep 3
6735
6736         local before=$(do_facet mds1 date +%s)
6737         local skew=$(($(date +%s) - before + 1))
6738
6739         if (( skew < 0 && skew > -5 )); then
6740                 sleep $((0 - skew + 1))
6741                 skew=0
6742         fi
6743
6744         # Set the dir stripe params to limit files all on MDT0,
6745         # otherwise we need to calc the max clock skew between
6746         # the client and MDTs.
6747         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6748         sleep 2
6749         touch $negref || error "touch $negref failed"
6750
6751         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6752         local nums=$($cmd | wc -l)
6753         local expected=$(((NUMFILES + 1) * NUMDIRS))
6754
6755         [ $nums -eq $expected ] ||
6756                 error "'$cmd' wrong: found $nums, expected $expected"
6757
6758         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6759         nums=$($cmd | wc -l)
6760         expected=$((NUMFILES + 1))
6761         [ $nums -eq $expected ] ||
6762                 error "'$cmd' wrong: found $nums, expected $expected"
6763
6764         [ $skew -lt 0 ] && return
6765
6766         local after=$(do_facet mds1 date +%s)
6767         local age=$((after - before + 1 + skew))
6768
6769         cmd="$LFS find $dir -btime -${age}s -type f"
6770         nums=$($cmd | wc -l)
6771         expected=$(((NUMFILES + 1) * NUMDIRS))
6772
6773         echo "Clock skew between client and server: $skew, age:$age"
6774         [ $nums -eq $expected ] ||
6775                 error "'$cmd' wrong: found $nums, expected $expected"
6776
6777         expected=$(($NUMDIRS + 1))
6778         cmd="$LFS find $dir -btime -${age}s -type d"
6779         nums=$($cmd | wc -l)
6780         [ $nums -eq $expected ] ||
6781                 error "'$cmd' wrong: found $nums, expected $expected"
6782         rm -f $ref $negref || error "Failed to remove $ref $negref"
6783 }
6784 run_test 56od "check lfs find -btime with units"
6785
6786 test_56p() {
6787         [ $RUNAS_ID -eq $UID ] &&
6788                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6789
6790         local dir=$DIR/$tdir
6791
6792         setup_56 $dir $NUMFILES $NUMDIRS
6793         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6794
6795         local expected=$NUMFILES
6796         local cmd="$LFS find -uid $RUNAS_ID $dir"
6797         local nums=$($cmd | wc -l)
6798
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801
6802         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6803         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6804         nums=$($cmd | wc -l)
6805         [ $nums -eq $expected ] ||
6806                 error "'$cmd' wrong: found $nums, expected $expected"
6807 }
6808 run_test 56p "check lfs find -uid and ! -uid"
6809
6810 test_56q() {
6811         [ $RUNAS_ID -eq $UID ] &&
6812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6813
6814         local dir=$DIR/$tdir
6815
6816         setup_56 $dir $NUMFILES $NUMDIRS
6817         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6818
6819         local expected=$NUMFILES
6820         local cmd="$LFS find -gid $RUNAS_GID $dir"
6821         local nums=$($cmd | wc -l)
6822
6823         [ $nums -eq $expected ] ||
6824                 error "'$cmd' wrong: found $nums, expected $expected"
6825
6826         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6827         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6828         nums=$($cmd | wc -l)
6829         [ $nums -eq $expected ] ||
6830                 error "'$cmd' wrong: found $nums, expected $expected"
6831 }
6832 run_test 56q "check lfs find -gid and ! -gid"
6833
6834 test_56r() {
6835         local dir=$DIR/$tdir
6836
6837         setup_56 $dir $NUMFILES $NUMDIRS
6838
6839         local expected=12
6840         local cmd="$LFS find -size 0 -type f -lazy $dir"
6841         local nums=$($cmd | wc -l)
6842
6843         [ $nums -eq $expected ] ||
6844                 error "'$cmd' wrong: found $nums, expected $expected"
6845         cmd="$LFS find -size 0 -type f $dir"
6846         nums=$($cmd | wc -l)
6847         [ $nums -eq $expected ] ||
6848                 error "'$cmd' wrong: found $nums, expected $expected"
6849
6850         expected=0
6851         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6852         nums=$($cmd | wc -l)
6853         [ $nums -eq $expected ] ||
6854                 error "'$cmd' wrong: found $nums, expected $expected"
6855         cmd="$LFS find ! -size 0 -type f $dir"
6856         nums=$($cmd | wc -l)
6857         [ $nums -eq $expected ] ||
6858                 error "'$cmd' wrong: found $nums, expected $expected"
6859
6860         echo "test" > $dir/$tfile
6861         echo "test2" > $dir/$tfile.2 && sync
6862         expected=1
6863         cmd="$LFS find -size 5 -type f -lazy $dir"
6864         nums=$($cmd | wc -l)
6865         [ $nums -eq $expected ] ||
6866                 error "'$cmd' wrong: found $nums, expected $expected"
6867         cmd="$LFS find -size 5 -type f $dir"
6868         nums=$($cmd | wc -l)
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871
6872         expected=1
6873         cmd="$LFS find -size +5 -type f -lazy $dir"
6874         nums=$($cmd | wc -l)
6875         [ $nums -eq $expected ] ||
6876                 error "'$cmd' wrong: found $nums, expected $expected"
6877         cmd="$LFS find -size +5 -type f $dir"
6878         nums=$($cmd | wc -l)
6879         [ $nums -eq $expected ] ||
6880                 error "'$cmd' wrong: found $nums, expected $expected"
6881
6882         expected=2
6883         cmd="$LFS find -size +0 -type f -lazy $dir"
6884         nums=$($cmd | wc -l)
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887         cmd="$LFS find -size +0 -type f $dir"
6888         nums=$($cmd | wc -l)
6889         [ $nums -eq $expected ] ||
6890                 error "'$cmd' wrong: found $nums, expected $expected"
6891
6892         expected=2
6893         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6894         nums=$($cmd | wc -l)
6895         [ $nums -eq $expected ] ||
6896                 error "'$cmd' wrong: found $nums, expected $expected"
6897         cmd="$LFS find ! -size -5 -type f $dir"
6898         nums=$($cmd | wc -l)
6899         [ $nums -eq $expected ] ||
6900                 error "'$cmd' wrong: found $nums, expected $expected"
6901
6902         expected=12
6903         cmd="$LFS find -size -5 -type f -lazy $dir"
6904         nums=$($cmd | wc -l)
6905         [ $nums -eq $expected ] ||
6906                 error "'$cmd' wrong: found $nums, expected $expected"
6907         cmd="$LFS find -size -5 -type f $dir"
6908         nums=$($cmd | wc -l)
6909         [ $nums -eq $expected ] ||
6910                 error "'$cmd' wrong: found $nums, expected $expected"
6911 }
6912 run_test 56r "check lfs find -size works"
6913
6914 test_56ra_sub() {
6915         local expected=$1
6916         local glimpses=$2
6917         local cmd="$3"
6918
6919         cancel_lru_locks $OSC
6920
6921         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6922         local nums=$($cmd | wc -l)
6923
6924         [ $nums -eq $expected ] ||
6925                 error "'$cmd' wrong: found $nums, expected $expected"
6926
6927         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6928
6929         if (( rpcs_before + glimpses != rpcs_after )); then
6930                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6931                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6932
6933                 if [[ $glimpses == 0 ]]; then
6934                         error "'$cmd' should not send glimpse RPCs to OST"
6935                 else
6936                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6937                 fi
6938         fi
6939 }
6940
6941 test_56ra() {
6942         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6943                 skip "MDS < 2.12.58 doesn't return LSOM data"
6944         local dir=$DIR/$tdir
6945         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6946
6947         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6948
6949         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6950         $LCTL set_param -n llite.*.statahead_agl=0
6951         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6952
6953         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6954         # open and close all files to ensure LSOM is updated
6955         cancel_lru_locks $OSC
6956         find $dir -type f | xargs cat > /dev/null
6957
6958         #   expect_found  glimpse_rpcs  command_to_run
6959         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6960         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6961         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6962         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6963
6964         echo "test" > $dir/$tfile
6965         echo "test2" > $dir/$tfile.2 && sync
6966         cancel_lru_locks $OSC
6967         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6968
6969         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6970         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6971         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6972         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6973
6974         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6975         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6976         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6977         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6978         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6979         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6980 }
6981 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6982
6983 test_56rb() {
6984         local dir=$DIR/$tdir
6985         local tmp=$TMP/$tfile.log
6986         local mdt_idx;
6987
6988         test_mkdir -p $dir || error "failed to mkdir $dir"
6989         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6990                 error "failed to setstripe $dir/$tfile"
6991         mdt_idx=$($LFS getdirstripe -i $dir)
6992         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6993
6994         stack_trap "rm -f $tmp" EXIT
6995         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6996         ! grep -q obd_uuid $tmp ||
6997                 error "failed to find --size +100K --ost 0 $dir"
6998         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6999         ! grep -q obd_uuid $tmp ||
7000                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7001 }
7002 run_test 56rb "check lfs find --size --ost/--mdt works"
7003
7004 test_56rc() {
7005         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7006         local dir=$DIR/$tdir
7007         local found
7008
7009         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7010         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7011         (( $MDSCOUNT > 2 )) &&
7012                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7013         mkdir $dir/$tdir-{1..10}
7014         touch $dir/$tfile-{1..10}
7015
7016         found=$($LFS find $dir --mdt-count 2 | wc -l)
7017         expect=11
7018         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7019
7020         found=$($LFS find $dir -T +1 | wc -l)
7021         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7022         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7023
7024         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7025         expect=11
7026         (( $found == $expect )) || error "found $found all_char, expect $expect"
7027
7028         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7029         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7030         (( $found == $expect )) || error "found $found all_char, expect $expect"
7031 }
7032 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7033
7034 test_56s() { # LU-611 #LU-9369
7035         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7036
7037         local dir=$DIR/$tdir
7038         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7039
7040         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7041         for i in $(seq $NUMDIRS); do
7042                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7043         done
7044
7045         local expected=$NUMDIRS
7046         local cmd="$LFS find -c $OSTCOUNT $dir"
7047         local nums=$($cmd | wc -l)
7048
7049         [ $nums -eq $expected ] || {
7050                 $LFS getstripe -R $dir
7051                 error "'$cmd' wrong: found $nums, expected $expected"
7052         }
7053
7054         expected=$((NUMDIRS + onestripe))
7055         cmd="$LFS find -stripe-count +0 -type f $dir"
7056         nums=$($cmd | wc -l)
7057         [ $nums -eq $expected ] || {
7058                 $LFS getstripe -R $dir
7059                 error "'$cmd' wrong: found $nums, expected $expected"
7060         }
7061
7062         expected=$onestripe
7063         cmd="$LFS find -stripe-count 1 -type f $dir"
7064         nums=$($cmd | wc -l)
7065         [ $nums -eq $expected ] || {
7066                 $LFS getstripe -R $dir
7067                 error "'$cmd' wrong: found $nums, expected $expected"
7068         }
7069
7070         cmd="$LFS find -stripe-count -2 -type f $dir"
7071         nums=$($cmd | wc -l)
7072         [ $nums -eq $expected ] || {
7073                 $LFS getstripe -R $dir
7074                 error "'$cmd' wrong: found $nums, expected $expected"
7075         }
7076
7077         expected=0
7078         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7079         nums=$($cmd | wc -l)
7080         [ $nums -eq $expected ] || {
7081                 $LFS getstripe -R $dir
7082                 error "'$cmd' wrong: found $nums, expected $expected"
7083         }
7084 }
7085 run_test 56s "check lfs find -stripe-count works"
7086
7087 test_56t() { # LU-611 #LU-9369
7088         local dir=$DIR/$tdir
7089
7090         setup_56 $dir 0 $NUMDIRS
7091         for i in $(seq $NUMDIRS); do
7092                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7093         done
7094
7095         local expected=$NUMDIRS
7096         local cmd="$LFS find -S 8M $dir"
7097         local nums=$($cmd | wc -l)
7098
7099         [ $nums -eq $expected ] || {
7100                 $LFS getstripe -R $dir
7101                 error "'$cmd' wrong: found $nums, expected $expected"
7102         }
7103         rm -rf $dir
7104
7105         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7106
7107         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7108
7109         expected=$(((NUMDIRS + 1) * NUMFILES))
7110         cmd="$LFS find -stripe-size 512k -type f $dir"
7111         nums=$($cmd | wc -l)
7112         [ $nums -eq $expected ] ||
7113                 error "'$cmd' wrong: found $nums, expected $expected"
7114
7115         cmd="$LFS find -stripe-size +320k -type f $dir"
7116         nums=$($cmd | wc -l)
7117         [ $nums -eq $expected ] ||
7118                 error "'$cmd' wrong: found $nums, expected $expected"
7119
7120         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7121         cmd="$LFS find -stripe-size +200k -type f $dir"
7122         nums=$($cmd | wc -l)
7123         [ $nums -eq $expected ] ||
7124                 error "'$cmd' wrong: found $nums, expected $expected"
7125
7126         cmd="$LFS find -stripe-size -640k -type f $dir"
7127         nums=$($cmd | wc -l)
7128         [ $nums -eq $expected ] ||
7129                 error "'$cmd' wrong: found $nums, expected $expected"
7130
7131         expected=4
7132         cmd="$LFS find -stripe-size 256k -type f $dir"
7133         nums=$($cmd | wc -l)
7134         [ $nums -eq $expected ] ||
7135                 error "'$cmd' wrong: found $nums, expected $expected"
7136
7137         cmd="$LFS find -stripe-size -320k -type f $dir"
7138         nums=$($cmd | wc -l)
7139         [ $nums -eq $expected ] ||
7140                 error "'$cmd' wrong: found $nums, expected $expected"
7141
7142         expected=0
7143         cmd="$LFS find -stripe-size 1024k -type f $dir"
7144         nums=$($cmd | wc -l)
7145         [ $nums -eq $expected ] ||
7146                 error "'$cmd' wrong: found $nums, expected $expected"
7147 }
7148 run_test 56t "check lfs find -stripe-size works"
7149
7150 test_56u() { # LU-611
7151         local dir=$DIR/$tdir
7152
7153         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7154
7155         if [[ $OSTCOUNT -gt 1 ]]; then
7156                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7157                 onestripe=4
7158         else
7159                 onestripe=0
7160         fi
7161
7162         local expected=$(((NUMDIRS + 1) * NUMFILES))
7163         local cmd="$LFS find -stripe-index 0 -type f $dir"
7164         local nums=$($cmd | wc -l)
7165
7166         [ $nums -eq $expected ] ||
7167                 error "'$cmd' wrong: found $nums, expected $expected"
7168
7169         expected=$onestripe
7170         cmd="$LFS find -stripe-index 1 -type f $dir"
7171         nums=$($cmd | wc -l)
7172         [ $nums -eq $expected ] ||
7173                 error "'$cmd' wrong: found $nums, expected $expected"
7174
7175         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7176         nums=$($cmd | wc -l)
7177         [ $nums -eq $expected ] ||
7178                 error "'$cmd' wrong: found $nums, expected $expected"
7179
7180         expected=0
7181         # This should produce an error and not return any files
7182         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7183         nums=$($cmd 2>/dev/null | wc -l)
7184         [ $nums -eq $expected ] ||
7185                 error "'$cmd' wrong: found $nums, expected $expected"
7186
7187         if [[ $OSTCOUNT -gt 1 ]]; then
7188                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7189                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7190                 nums=$($cmd | wc -l)
7191                 [ $nums -eq $expected ] ||
7192                         error "'$cmd' wrong: found $nums, expected $expected"
7193         fi
7194 }
7195 run_test 56u "check lfs find -stripe-index works"
7196
7197 test_56v() {
7198         local mdt_idx=0
7199         local dir=$DIR/$tdir
7200
7201         setup_56 $dir $NUMFILES $NUMDIRS
7202
7203         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7204         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7205
7206         for file in $($LFS find -m $UUID $dir); do
7207                 file_midx=$($LFS getstripe -m $file)
7208                 [ $file_midx -eq $mdt_idx ] ||
7209                         error "lfs find -m $UUID != getstripe -m $file_midx"
7210         done
7211 }
7212 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7213
7214 test_56w() {
7215         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7217
7218         local dir=$DIR/$tdir
7219
7220         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7221
7222         local stripe_size=$($LFS getstripe -S -d $dir) ||
7223                 error "$LFS getstripe -S -d $dir failed"
7224         stripe_size=${stripe_size%% *}
7225
7226         local file_size=$((stripe_size * OSTCOUNT))
7227         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7228         local required_space=$((file_num * file_size))
7229         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7230                            head -n1)
7231         [[ $free_space -le $((required_space / 1024)) ]] &&
7232                 skip_env "need $required_space, have $free_space kbytes"
7233
7234         local dd_bs=65536
7235         local dd_count=$((file_size / dd_bs))
7236
7237         # write data into the files
7238         local i
7239         local j
7240         local file
7241
7242         for i in $(seq $NUMFILES); do
7243                 file=$dir/file$i
7244                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7245                         error "write data into $file failed"
7246         done
7247         for i in $(seq $NUMDIRS); do
7248                 for j in $(seq $NUMFILES); do
7249                         file=$dir/dir$i/file$j
7250                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7251                                 error "write data into $file failed"
7252                 done
7253         done
7254
7255         # $LFS_MIGRATE will fail if hard link migration is unsupported
7256         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7257                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7258                         error "creating links to $dir/dir1/file1 failed"
7259         fi
7260
7261         local expected=-1
7262
7263         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7264
7265         # lfs_migrate file
7266         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7267
7268         echo "$cmd"
7269         eval $cmd || error "$cmd failed"
7270
7271         check_stripe_count $dir/file1 $expected
7272
7273         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7274         then
7275                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7276                 # OST 1 if it is on OST 0. This file is small enough to
7277                 # be on only one stripe.
7278                 file=$dir/migr_1_ost
7279                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7280                         error "write data into $file failed"
7281                 local obdidx=$($LFS getstripe -i $file)
7282                 local oldmd5=$(md5sum $file)
7283                 local newobdidx=0
7284
7285                 [[ $obdidx -eq 0 ]] && newobdidx=1
7286                 cmd="$LFS migrate -i $newobdidx $file"
7287                 echo $cmd
7288                 eval $cmd || error "$cmd failed"
7289
7290                 local realobdix=$($LFS getstripe -i $file)
7291                 local newmd5=$(md5sum $file)
7292
7293                 [[ $newobdidx -ne $realobdix ]] &&
7294                         error "new OST is different (was=$obdidx, "\
7295                               "wanted=$newobdidx, got=$realobdix)"
7296                 [[ "$oldmd5" != "$newmd5" ]] &&
7297                         error "md5sum differ: $oldmd5, $newmd5"
7298         fi
7299
7300         # lfs_migrate dir
7301         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7302         echo "$cmd"
7303         eval $cmd || error "$cmd failed"
7304
7305         for j in $(seq $NUMFILES); do
7306                 check_stripe_count $dir/dir1/file$j $expected
7307         done
7308
7309         # lfs_migrate works with lfs find
7310         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7311              $LFS_MIGRATE -y -c $expected"
7312         echo "$cmd"
7313         eval $cmd || error "$cmd failed"
7314
7315         for i in $(seq 2 $NUMFILES); do
7316                 check_stripe_count $dir/file$i $expected
7317         done
7318         for i in $(seq 2 $NUMDIRS); do
7319                 for j in $(seq $NUMFILES); do
7320                 check_stripe_count $dir/dir$i/file$j $expected
7321                 done
7322         done
7323 }
7324 run_test 56w "check lfs_migrate -c stripe_count works"
7325
7326 test_56wb() {
7327         local file1=$DIR/$tdir/file1
7328         local create_pool=false
7329         local initial_pool=$($LFS getstripe -p $DIR)
7330         local pool_list=()
7331         local pool=""
7332
7333         echo -n "Creating test dir..."
7334         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7335         echo "done."
7336
7337         echo -n "Creating test file..."
7338         touch $file1 || error "cannot create file"
7339         echo "done."
7340
7341         echo -n "Detecting existing pools..."
7342         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7343
7344         if [ ${#pool_list[@]} -gt 0 ]; then
7345                 echo "${pool_list[@]}"
7346                 for thispool in "${pool_list[@]}"; do
7347                         if [[ -z "$initial_pool" ||
7348                               "$initial_pool" != "$thispool" ]]; then
7349                                 pool="$thispool"
7350                                 echo "Using existing pool '$pool'"
7351                                 break
7352                         fi
7353                 done
7354         else
7355                 echo "none detected."
7356         fi
7357         if [ -z "$pool" ]; then
7358                 pool=${POOL:-testpool}
7359                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7360                 echo -n "Creating pool '$pool'..."
7361                 create_pool=true
7362                 pool_add $pool &> /dev/null ||
7363                         error "pool_add failed"
7364                 echo "done."
7365
7366                 echo -n "Adding target to pool..."
7367                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7368                         error "pool_add_targets failed"
7369                 echo "done."
7370         fi
7371
7372         echo -n "Setting pool using -p option..."
7373         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7374                 error "migrate failed rc = $?"
7375         echo "done."
7376
7377         echo -n "Verifying test file is in pool after migrating..."
7378         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7379                 error "file was not migrated to pool $pool"
7380         echo "done."
7381
7382         echo -n "Removing test file from pool '$pool'..."
7383         # "lfs migrate $file" won't remove the file from the pool
7384         # until some striping information is changed.
7385         $LFS migrate -c 1 $file1 &> /dev/null ||
7386                 error "cannot remove from pool"
7387         [ "$($LFS getstripe -p $file1)" ] &&
7388                 error "pool still set"
7389         echo "done."
7390
7391         echo -n "Setting pool using --pool option..."
7392         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7393                 error "migrate failed rc = $?"
7394         echo "done."
7395
7396         # Clean up
7397         rm -f $file1
7398         if $create_pool; then
7399                 destroy_test_pools 2> /dev/null ||
7400                         error "destroy test pools failed"
7401         fi
7402 }
7403 run_test 56wb "check lfs_migrate pool support"
7404
7405 test_56wc() {
7406         local file1="$DIR/$tdir/file1"
7407         local parent_ssize
7408         local parent_scount
7409         local cur_ssize
7410         local cur_scount
7411         local orig_ssize
7412
7413         echo -n "Creating test dir..."
7414         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7415         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7416                 error "cannot set stripe by '-S 1M -c 1'"
7417         echo "done"
7418
7419         echo -n "Setting initial stripe for test file..."
7420         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7421                 error "cannot set stripe"
7422         cur_ssize=$($LFS getstripe -S "$file1")
7423         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7424         echo "done."
7425
7426         # File currently set to -S 512K -c 1
7427
7428         # Ensure -c and -S options are rejected when -R is set
7429         echo -n "Verifying incompatible options are detected..."
7430         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7431                 error "incompatible -c and -R options not detected"
7432         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7433                 error "incompatible -S and -R options not detected"
7434         echo "done."
7435
7436         # Ensure unrecognized options are passed through to 'lfs migrate'
7437         echo -n "Verifying -S option is passed through to lfs migrate..."
7438         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7439                 error "migration failed"
7440         cur_ssize=$($LFS getstripe -S "$file1")
7441         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7442         echo "done."
7443
7444         # File currently set to -S 1M -c 1
7445
7446         # Ensure long options are supported
7447         echo -n "Verifying long options supported..."
7448         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7449                 error "long option without argument not supported"
7450         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7451                 error "long option with argument not supported"
7452         cur_ssize=$($LFS getstripe -S "$file1")
7453         [ $cur_ssize -eq 524288 ] ||
7454                 error "migrate --stripe-size $cur_ssize != 524288"
7455         echo "done."
7456
7457         # File currently set to -S 512K -c 1
7458
7459         if [ "$OSTCOUNT" -gt 1 ]; then
7460                 echo -n "Verifying explicit stripe count can be set..."
7461                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7462                         error "migrate failed"
7463                 cur_scount=$($LFS getstripe -c "$file1")
7464                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7465                 echo "done."
7466         fi
7467
7468         # File currently set to -S 512K -c 1 or -S 512K -c 2
7469
7470         # Ensure parent striping is used if -R is set, and no stripe
7471         # count or size is specified
7472         echo -n "Setting stripe for parent directory..."
7473         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7474                 error "cannot set stripe '-S 2M -c 1'"
7475         echo "done."
7476
7477         echo -n "Verifying restripe option uses parent stripe settings..."
7478         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7479         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7480         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7481                 error "migrate failed"
7482         cur_ssize=$($LFS getstripe -S "$file1")
7483         [ $cur_ssize -eq $parent_ssize ] ||
7484                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7485         cur_scount=$($LFS getstripe -c "$file1")
7486         [ $cur_scount -eq $parent_scount ] ||
7487                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7488         echo "done."
7489
7490         # File currently set to -S 1M -c 1
7491
7492         # Ensure striping is preserved if -R is not set, and no stripe
7493         # count or size is specified
7494         echo -n "Verifying striping size preserved when not specified..."
7495         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7496         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7497                 error "cannot set stripe on parent directory"
7498         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7499                 error "migrate failed"
7500         cur_ssize=$($LFS getstripe -S "$file1")
7501         [ $cur_ssize -eq $orig_ssize ] ||
7502                 error "migrate by default $cur_ssize != $orig_ssize"
7503         echo "done."
7504
7505         # Ensure file name properly detected when final option has no argument
7506         echo -n "Verifying file name properly detected..."
7507         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7508                 error "file name interpreted as option argument"
7509         echo "done."
7510
7511         # Clean up
7512         rm -f "$file1"
7513 }
7514 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7515
7516 test_56wd() {
7517         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7518
7519         local file1=$DIR/$tdir/file1
7520
7521         echo -n "Creating test dir..."
7522         test_mkdir $DIR/$tdir || error "cannot create dir"
7523         echo "done."
7524
7525         echo -n "Creating test file..."
7526         touch $file1
7527         echo "done."
7528
7529         # Ensure 'lfs migrate' will fail by using a non-existent option,
7530         # and make sure rsync is not called to recover
7531         echo -n "Make sure --no-rsync option works..."
7532         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7533                 grep -q 'refusing to fall back to rsync' ||
7534                 error "rsync was called with --no-rsync set"
7535         echo "done."
7536
7537         # Ensure rsync is called without trying 'lfs migrate' first
7538         echo -n "Make sure --rsync option works..."
7539         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7540                 grep -q 'falling back to rsync' &&
7541                 error "lfs migrate was called with --rsync set"
7542         echo "done."
7543
7544         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7545         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7546                 grep -q 'at the same time' ||
7547                 error "--rsync and --no-rsync accepted concurrently"
7548         echo "done."
7549
7550         # Clean up
7551         rm -f $file1
7552 }
7553 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7554
7555 test_56we() {
7556         local td=$DIR/$tdir
7557         local tf=$td/$tfile
7558
7559         test_mkdir $td || error "cannot create $td"
7560         touch $tf || error "cannot touch $tf"
7561
7562         echo -n "Make sure --non-direct|-D works..."
7563         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7564                 grep -q "lfs migrate --non-direct" ||
7565                 error "--non-direct option cannot work correctly"
7566         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7567                 grep -q "lfs migrate -D" ||
7568                 error "-D option cannot work correctly"
7569         echo "done."
7570 }
7571 run_test 56we "check lfs_migrate --non-direct|-D support"
7572
7573 test_56x() {
7574         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7575         check_swap_layouts_support
7576
7577         local dir=$DIR/$tdir
7578         local ref1=/etc/passwd
7579         local file1=$dir/file1
7580
7581         test_mkdir $dir || error "creating dir $dir"
7582         $LFS setstripe -c 2 $file1
7583         cp $ref1 $file1
7584         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7585         stripe=$($LFS getstripe -c $file1)
7586         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7587         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7588
7589         # clean up
7590         rm -f $file1
7591 }
7592 run_test 56x "lfs migration support"
7593
7594 test_56xa() {
7595         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7596         check_swap_layouts_support
7597
7598         local dir=$DIR/$tdir/$testnum
7599
7600         test_mkdir -p $dir
7601
7602         local ref1=/etc/passwd
7603         local file1=$dir/file1
7604
7605         $LFS setstripe -c 2 $file1
7606         cp $ref1 $file1
7607         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7608
7609         local stripe=$($LFS getstripe -c $file1)
7610
7611         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7612         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7613
7614         # clean up
7615         rm -f $file1
7616 }
7617 run_test 56xa "lfs migration --block support"
7618
7619 check_migrate_links() {
7620         local dir="$1"
7621         local file1="$dir/file1"
7622         local begin="$2"
7623         local count="$3"
7624         local runas="$4"
7625         local total_count=$(($begin + $count - 1))
7626         local symlink_count=10
7627         local uniq_count=10
7628
7629         if [ ! -f "$file1" ]; then
7630                 echo -n "creating initial file..."
7631                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7632                         error "cannot setstripe initial file"
7633                 echo "done"
7634
7635                 echo -n "creating symlinks..."
7636                 for s in $(seq 1 $symlink_count); do
7637                         ln -s "$file1" "$dir/slink$s" ||
7638                                 error "cannot create symlinks"
7639                 done
7640                 echo "done"
7641
7642                 echo -n "creating nonlinked files..."
7643                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7644                         error "cannot create nonlinked files"
7645                 echo "done"
7646         fi
7647
7648         # create hard links
7649         if [ ! -f "$dir/file$total_count" ]; then
7650                 echo -n "creating hard links $begin:$total_count..."
7651                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7652                         /dev/null || error "cannot create hard links"
7653                 echo "done"
7654         fi
7655
7656         echo -n "checking number of hard links listed in xattrs..."
7657         local fid=$($LFS getstripe -F "$file1")
7658         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7659
7660         echo "${#paths[*]}"
7661         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7662                         skip "hard link list has unexpected size, skipping test"
7663         fi
7664         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7665                         error "link names should exceed xattrs size"
7666         fi
7667
7668         echo -n "migrating files..."
7669         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7670         local rc=$?
7671         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7672         echo "done"
7673
7674         # make sure all links have been properly migrated
7675         echo -n "verifying files..."
7676         fid=$($LFS getstripe -F "$file1") ||
7677                 error "cannot get fid for file $file1"
7678         for i in $(seq 2 $total_count); do
7679                 local fid2=$($LFS getstripe -F $dir/file$i)
7680
7681                 [ "$fid2" == "$fid" ] ||
7682                         error "migrated hard link has mismatched FID"
7683         done
7684
7685         # make sure hard links were properly detected, and migration was
7686         # performed only once for the entire link set; nonlinked files should
7687         # also be migrated
7688         local actual=$(grep -c 'done' <<< "$migrate_out")
7689         local expected=$(($uniq_count + 1))
7690
7691         [ "$actual" -eq  "$expected" ] ||
7692                 error "hard links individually migrated ($actual != $expected)"
7693
7694         # make sure the correct number of hard links are present
7695         local hardlinks=$(stat -c '%h' "$file1")
7696
7697         [ $hardlinks -eq $total_count ] ||
7698                 error "num hard links $hardlinks != $total_count"
7699         echo "done"
7700
7701         return 0
7702 }
7703
7704 test_56xb() {
7705         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7706                 skip "Need MDS version at least 2.10.55"
7707
7708         local dir="$DIR/$tdir"
7709
7710         test_mkdir "$dir" || error "cannot create dir $dir"
7711
7712         echo "testing lfs migrate mode when all links fit within xattrs"
7713         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7714
7715         echo "testing rsync mode when all links fit within xattrs"
7716         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7717
7718         echo "testing lfs migrate mode when all links do not fit within xattrs"
7719         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7720
7721         echo "testing rsync mode when all links do not fit within xattrs"
7722         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7723
7724         chown -R $RUNAS_ID $dir
7725         echo "testing non-root lfs migrate mode when not all links are in xattr"
7726         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7727
7728         # clean up
7729         rm -rf $dir
7730 }
7731 run_test 56xb "lfs migration hard link support"
7732
7733 test_56xc() {
7734         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7735
7736         local dir="$DIR/$tdir"
7737
7738         test_mkdir "$dir" || error "cannot create dir $dir"
7739
7740         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7741         echo -n "Setting initial stripe for 20MB test file..."
7742         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7743                 error "cannot setstripe 20MB file"
7744         echo "done"
7745         echo -n "Sizing 20MB test file..."
7746         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7747         echo "done"
7748         echo -n "Verifying small file autostripe count is 1..."
7749         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7750                 error "cannot migrate 20MB file"
7751         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7752                 error "cannot get stripe for $dir/20mb"
7753         [ $stripe_count -eq 1 ] ||
7754                 error "unexpected stripe count $stripe_count for 20MB file"
7755         rm -f "$dir/20mb"
7756         echo "done"
7757
7758         # Test 2: File is small enough to fit within the available space on
7759         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7760         # have at least an additional 1KB for each desired stripe for test 3
7761         echo -n "Setting stripe for 1GB test file..."
7762         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7763         echo "done"
7764         echo -n "Sizing 1GB test file..."
7765         # File size is 1GB + 3KB
7766         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7767         echo "done"
7768
7769         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7770         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7771         if (( avail > 524288 * OSTCOUNT )); then
7772                 echo -n "Migrating 1GB file..."
7773                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7774                         error "cannot migrate 1GB file"
7775                 echo "done"
7776                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7777                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7778                         error "cannot getstripe for 1GB file"
7779                 [ $stripe_count -eq 2 ] ||
7780                         error "unexpected stripe count $stripe_count != 2"
7781                 echo "done"
7782         fi
7783
7784         # Test 3: File is too large to fit within the available space on
7785         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7786         if [ $OSTCOUNT -ge 3 ]; then
7787                 # The required available space is calculated as
7788                 # file size (1GB + 3KB) / OST count (3).
7789                 local kb_per_ost=349526
7790
7791                 echo -n "Migrating 1GB file with limit..."
7792                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7793                         error "cannot migrate 1GB file with limit"
7794                 echo "done"
7795
7796                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7797                 echo -n "Verifying 1GB autostripe count with limited space..."
7798                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7799                         error "unexpected stripe count $stripe_count (min 3)"
7800                 echo "done"
7801         fi
7802
7803         # clean up
7804         rm -rf $dir
7805 }
7806 run_test 56xc "lfs migration autostripe"
7807
7808 test_56xd() {
7809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7810
7811         local dir=$DIR/$tdir
7812         local f_mgrt=$dir/$tfile.mgrt
7813         local f_yaml=$dir/$tfile.yaml
7814         local f_copy=$dir/$tfile.copy
7815         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7816         local layout_copy="-c 2 -S 2M -i 1"
7817         local yamlfile=$dir/yamlfile
7818         local layout_before;
7819         local layout_after;
7820
7821         test_mkdir "$dir" || error "cannot create dir $dir"
7822         $LFS setstripe $layout_yaml $f_yaml ||
7823                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7824         $LFS getstripe --yaml $f_yaml > $yamlfile
7825         $LFS setstripe $layout_copy $f_copy ||
7826                 error "cannot setstripe $f_copy with layout $layout_copy"
7827         touch $f_mgrt
7828         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7829
7830         # 1. test option --yaml
7831         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7832                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7833         layout_before=$(get_layout_param $f_yaml)
7834         layout_after=$(get_layout_param $f_mgrt)
7835         [ "$layout_after" == "$layout_before" ] ||
7836                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7837
7838         # 2. test option --copy
7839         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7840                 error "cannot migrate $f_mgrt with --copy $f_copy"
7841         layout_before=$(get_layout_param $f_copy)
7842         layout_after=$(get_layout_param $f_mgrt)
7843         [ "$layout_after" == "$layout_before" ] ||
7844                 error "lfs_migrate --copy: $layout_after != $layout_before"
7845 }
7846 run_test 56xd "check lfs_migrate --yaml and --copy support"
7847
7848 test_56xe() {
7849         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7850
7851         local dir=$DIR/$tdir
7852         local f_comp=$dir/$tfile
7853         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7854         local layout_before=""
7855         local layout_after=""
7856
7857         test_mkdir "$dir" || error "cannot create dir $dir"
7858         $LFS setstripe $layout $f_comp ||
7859                 error "cannot setstripe $f_comp with layout $layout"
7860         layout_before=$(get_layout_param $f_comp)
7861         dd if=/dev/zero of=$f_comp bs=1M count=4
7862
7863         # 1. migrate a comp layout file by lfs_migrate
7864         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7865         layout_after=$(get_layout_param $f_comp)
7866         [ "$layout_before" == "$layout_after" ] ||
7867                 error "lfs_migrate: $layout_before != $layout_after"
7868
7869         # 2. migrate a comp layout file by lfs migrate
7870         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7871         layout_after=$(get_layout_param $f_comp)
7872         [ "$layout_before" == "$layout_after" ] ||
7873                 error "lfs migrate: $layout_before != $layout_after"
7874 }
7875 run_test 56xe "migrate a composite layout file"
7876
7877 test_56xf() {
7878         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7879
7880         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7881                 skip "Need server version at least 2.13.53"
7882
7883         local dir=$DIR/$tdir
7884         local f_comp=$dir/$tfile
7885         local layout="-E 1M -c1 -E -1 -c2"
7886         local fid_before=""
7887         local fid_after=""
7888
7889         test_mkdir "$dir" || error "cannot create dir $dir"
7890         $LFS setstripe $layout $f_comp ||
7891                 error "cannot setstripe $f_comp with layout $layout"
7892         fid_before=$($LFS getstripe --fid $f_comp)
7893         dd if=/dev/zero of=$f_comp bs=1M count=4
7894
7895         # 1. migrate a comp layout file to a comp layout
7896         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7897         fid_after=$($LFS getstripe --fid $f_comp)
7898         [ "$fid_before" == "$fid_after" ] ||
7899                 error "comp-to-comp migrate: $fid_before != $fid_after"
7900
7901         # 2. migrate a comp layout file to a plain layout
7902         $LFS migrate -c2 $f_comp ||
7903                 error "cannot migrate $f_comp by lfs migrate"
7904         fid_after=$($LFS getstripe --fid $f_comp)
7905         [ "$fid_before" == "$fid_after" ] ||
7906                 error "comp-to-plain migrate: $fid_before != $fid_after"
7907
7908         # 3. migrate a plain layout file to a comp layout
7909         $LFS migrate $layout $f_comp ||
7910                 error "cannot migrate $f_comp by lfs migrate"
7911         fid_after=$($LFS getstripe --fid $f_comp)
7912         [ "$fid_before" == "$fid_after" ] ||
7913                 error "plain-to-comp migrate: $fid_before != $fid_after"
7914 }
7915 run_test 56xf "FID is not lost during migration of a composite layout file"
7916
7917 check_file_ost_range() {
7918         local file="$1"
7919         shift
7920         local range="$*"
7921         local -a file_range
7922         local idx
7923
7924         file_range=($($LFS getstripe -y "$file" |
7925                 awk '/l_ost_idx:/ { print $NF }'))
7926
7927         if [[ "${#file_range[@]}" = 0 ]]; then
7928                 echo "No osts found for $file"
7929                 return 1
7930         fi
7931
7932         for idx in "${file_range[@]}"; do
7933                 [[ " $range " =~ " $idx " ]] ||
7934                         return 1
7935         done
7936
7937         return 0
7938 }
7939
7940 sub_test_56xg() {
7941         local stripe_opt="$1"
7942         local pool="$2"
7943         shift 2
7944         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7945
7946         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7947                 error "Fail to migrate $tfile on $pool"
7948         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7949                 error "$tfile is not in pool $pool"
7950         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7951                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7952 }
7953
7954 test_56xg() {
7955         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7956         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7957         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7958                 skip "Need MDS version newer than 2.14.52"
7959
7960         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7961         local -a pool_ranges=("0 0" "1 1" "0 1")
7962
7963         # init pools
7964         for i in "${!pool_names[@]}"; do
7965                 pool_add ${pool_names[$i]} ||
7966                         error "pool_add failed (pool: ${pool_names[$i]})"
7967                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7968                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7969         done
7970
7971         # init the file to migrate
7972         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7973                 error "Unable to create $tfile on OST1"
7974         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7975                 error "Unable to write on $tfile"
7976
7977         echo "1. migrate $tfile on pool ${pool_names[0]}"
7978         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7979
7980         echo "2. migrate $tfile on pool ${pool_names[2]}"
7981         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7982
7983         echo "3. migrate $tfile on pool ${pool_names[1]}"
7984         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7985
7986         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7987         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7988         echo
7989
7990         # Clean pools
7991         destroy_test_pools ||
7992                 error "pool_destroy failed"
7993 }
7994 run_test 56xg "lfs migrate pool support"
7995
7996 test_56y() {
7997         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7998                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7999
8000         local res=""
8001         local dir=$DIR/$tdir
8002         local f1=$dir/file1
8003         local f2=$dir/file2
8004
8005         test_mkdir -p $dir || error "creating dir $dir"
8006         touch $f1 || error "creating std file $f1"
8007         $MULTIOP $f2 H2c || error "creating released file $f2"
8008
8009         # a directory can be raid0, so ask only for files
8010         res=$($LFS find $dir -L raid0 -type f | wc -l)
8011         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8012
8013         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8014         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8015
8016         # only files can be released, so no need to force file search
8017         res=$($LFS find $dir -L released)
8018         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8019
8020         res=$($LFS find $dir -type f \! -L released)
8021         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8022 }
8023 run_test 56y "lfs find -L raid0|released"
8024
8025 test_56z() { # LU-4824
8026         # This checks to make sure 'lfs find' continues after errors
8027         # There are two classes of errors that should be caught:
8028         # - If multiple paths are provided, all should be searched even if one
8029         #   errors out
8030         # - If errors are encountered during the search, it should not terminate
8031         #   early
8032         local dir=$DIR/$tdir
8033         local i
8034
8035         test_mkdir $dir
8036         for i in d{0..9}; do
8037                 test_mkdir $dir/$i
8038                 touch $dir/$i/$tfile
8039         done
8040         $LFS find $DIR/non_existent_dir $dir &&
8041                 error "$LFS find did not return an error"
8042         # Make a directory unsearchable. This should NOT be the last entry in
8043         # directory order.  Arbitrarily pick the 6th entry
8044         chmod 700 $($LFS find $dir -type d | sed '6!d')
8045
8046         $RUNAS $LFS find $DIR/non_existent $dir
8047         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8048
8049         # The user should be able to see 10 directories and 9 files
8050         (( count == 19 )) ||
8051                 error "$LFS find found $count != 19 entries after error"
8052 }
8053 run_test 56z "lfs find should continue after an error"
8054
8055 test_56aa() { # LU-5937
8056         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8057
8058         local dir=$DIR/$tdir
8059
8060         mkdir $dir
8061         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8062
8063         createmany -o $dir/striped_dir/${tfile}- 1024
8064         local dirs=$($LFS find --size +8k $dir/)
8065
8066         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8067 }
8068 run_test 56aa "lfs find --size under striped dir"
8069
8070 test_56ab() { # LU-10705
8071         test_mkdir $DIR/$tdir
8072         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8073         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8074         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8075         # Flush writes to ensure valid blocks.  Need to be more thorough for
8076         # ZFS, since blocks are not allocated/returned to client immediately.
8077         sync_all_data
8078         wait_zfs_commit ost1 2
8079         cancel_lru_locks osc
8080         ls -ls $DIR/$tdir
8081
8082         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8083
8084         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8085
8086         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8087         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8088
8089         rm -f $DIR/$tdir/$tfile.[123]
8090 }
8091 run_test 56ab "lfs find --blocks"
8092
8093 # LU-11188
8094 test_56aca() {
8095         local dir="$DIR/$tdir"
8096         local perms=(001 002 003 004 005 006 007
8097                      010 020 030 040 050 060 070
8098                      100 200 300 400 500 600 700
8099                      111 222 333 444 555 666 777)
8100         local perm_minus=(8 8 4 8 4 4 2
8101                           8 8 4 8 4 4 2
8102                           8 8 4 8 4 4 2
8103                           4 4 2 4 2 2 1)
8104         local perm_slash=(8  8 12  8 12 12 14
8105                           8  8 12  8 12 12 14
8106                           8  8 12  8 12 12 14
8107                          16 16 24 16 24 24 28)
8108
8109         test_mkdir "$dir"
8110         for perm in ${perms[*]}; do
8111                 touch "$dir/$tfile.$perm"
8112                 chmod $perm "$dir/$tfile.$perm"
8113         done
8114
8115         for ((i = 0; i < ${#perms[*]}; i++)); do
8116                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8117                 (( $num == 1 )) ||
8118                         error "lfs find -perm ${perms[i]}:"\
8119                               "$num != 1"
8120
8121                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8122                 (( $num == ${perm_minus[i]} )) ||
8123                         error "lfs find -perm -${perms[i]}:"\
8124                               "$num != ${perm_minus[i]}"
8125
8126                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8127                 (( $num == ${perm_slash[i]} )) ||
8128                         error "lfs find -perm /${perms[i]}:"\
8129                               "$num != ${perm_slash[i]}"
8130         done
8131 }
8132 run_test 56aca "check lfs find -perm with octal representation"
8133
8134 test_56acb() {
8135         local dir=$DIR/$tdir
8136         # p is the permission of write and execute for user, group and other
8137         # without the umask. It is used to test +wx.
8138         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8139         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8140         local symbolic=(+t  a+t u+t g+t o+t
8141                         g+s u+s o+s +s o+sr
8142                         o=r,ug+o,u+w
8143                         u+ g+ o+ a+ ugo+
8144                         u- g- o- a- ugo-
8145                         u= g= o= a= ugo=
8146                         o=r,ug+o,u+w u=r,a+u,u+w
8147                         g=r,ugo=g,u+w u+x,+X +X
8148                         u+x,u+X u+X u+x,g+X o+r,+X
8149                         u+x,go+X +wx +rwx)
8150
8151         test_mkdir $dir
8152         for perm in ${perms[*]}; do
8153                 touch "$dir/$tfile.$perm"
8154                 chmod $perm "$dir/$tfile.$perm"
8155         done
8156
8157         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8158                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8159
8160                 (( $num == 1 )) ||
8161                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8162         done
8163 }
8164 run_test 56acb "check lfs find -perm with symbolic representation"
8165
8166 test_56acc() {
8167         local dir=$DIR/$tdir
8168         local tests="17777 787 789 abcd
8169                 ug=uu ug=a ug=gu uo=ou urw
8170                 u+xg+x a=r,u+x,"
8171
8172         test_mkdir $dir
8173         for err in $tests; do
8174                 if $LFS find $dir -perm $err 2>/dev/null; then
8175                         error "lfs find -perm $err: parsing should have failed"
8176                 fi
8177         done
8178 }
8179 run_test 56acc "check parsing error for lfs find -perm"
8180
8181 test_56ba() {
8182         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8183                 skip "Need MDS version at least 2.10.50"
8184
8185         # Create composite files with one component
8186         local dir=$DIR/$tdir
8187
8188         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8189         # Create composite files with three components
8190         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8191         # Create non-composite files
8192         createmany -o $dir/${tfile}- 10
8193
8194         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8195
8196         [[ $nfiles == 10 ]] ||
8197                 error "lfs find -E 1M found $nfiles != 10 files"
8198
8199         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8200         [[ $nfiles == 25 ]] ||
8201                 error "lfs find ! -E 1M found $nfiles != 25 files"
8202
8203         # All files have a component that starts at 0
8204         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8205         [[ $nfiles == 35 ]] ||
8206                 error "lfs find --component-start 0 - $nfiles != 35 files"
8207
8208         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8209         [[ $nfiles == 15 ]] ||
8210                 error "lfs find --component-start 2M - $nfiles != 15 files"
8211
8212         # All files created here have a componenet that does not starts at 2M
8213         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8214         [[ $nfiles == 35 ]] ||
8215                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8216
8217         # Find files with a specified number of components
8218         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8219         [[ $nfiles == 15 ]] ||
8220                 error "lfs find --component-count 3 - $nfiles != 15 files"
8221
8222         # Remember non-composite files have a component count of zero
8223         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8224         [[ $nfiles == 10 ]] ||
8225                 error "lfs find --component-count 0 - $nfiles != 10 files"
8226
8227         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8228         [[ $nfiles == 20 ]] ||
8229                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8230
8231         # All files have a flag called "init"
8232         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8233         [[ $nfiles == 35 ]] ||
8234                 error "lfs find --component-flags init - $nfiles != 35 files"
8235
8236         # Multi-component files will have a component not initialized
8237         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8238         [[ $nfiles == 15 ]] ||
8239                 error "lfs find !--component-flags init - $nfiles != 15 files"
8240
8241         rm -rf $dir
8242
8243 }
8244 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8245
8246 test_56ca() {
8247         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8248                 skip "Need MDS version at least 2.10.57"
8249
8250         local td=$DIR/$tdir
8251         local tf=$td/$tfile
8252         local dir
8253         local nfiles
8254         local cmd
8255         local i
8256         local j
8257
8258         # create mirrored directories and mirrored files
8259         mkdir $td || error "mkdir $td failed"
8260         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8261         createmany -o $tf- 10 || error "create $tf- failed"
8262
8263         for i in $(seq 2); do
8264                 dir=$td/dir$i
8265                 mkdir $dir || error "mkdir $dir failed"
8266                 $LFS mirror create -N$((3 + i)) $dir ||
8267                         error "create mirrored dir $dir failed"
8268                 createmany -o $dir/$tfile- 10 ||
8269                         error "create $dir/$tfile- failed"
8270         done
8271
8272         # change the states of some mirrored files
8273         echo foo > $tf-6
8274         for i in $(seq 2); do
8275                 dir=$td/dir$i
8276                 for j in $(seq 4 9); do
8277                         echo foo > $dir/$tfile-$j
8278                 done
8279         done
8280
8281         # find mirrored files with specific mirror count
8282         cmd="$LFS find --mirror-count 3 --type f $td"
8283         nfiles=$($cmd | wc -l)
8284         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8285
8286         cmd="$LFS find ! --mirror-count 3 --type f $td"
8287         nfiles=$($cmd | wc -l)
8288         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8289
8290         cmd="$LFS find --mirror-count +2 --type f $td"
8291         nfiles=$($cmd | wc -l)
8292         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8293
8294         cmd="$LFS find --mirror-count -6 --type f $td"
8295         nfiles=$($cmd | wc -l)
8296         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8297
8298         # find mirrored files with specific file state
8299         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8300         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8301
8302         cmd="$LFS find --mirror-state=ro --type f $td"
8303         nfiles=$($cmd | wc -l)
8304         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8305
8306         cmd="$LFS find ! --mirror-state=ro --type f $td"
8307         nfiles=$($cmd | wc -l)
8308         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8309
8310         cmd="$LFS find --mirror-state=wp --type f $td"
8311         nfiles=$($cmd | wc -l)
8312         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8313
8314         cmd="$LFS find ! --mirror-state=sp --type f $td"
8315         nfiles=$($cmd | wc -l)
8316         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8317 }
8318 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8319
8320 test_56da() { # LU-14179
8321         local path=$DIR/$tdir
8322
8323         test_mkdir $path
8324         cd $path
8325
8326         local longdir=$(str_repeat 'a' 255)
8327
8328         for i in {1..15}; do
8329                 path=$path/$longdir
8330                 test_mkdir $longdir
8331                 cd $longdir
8332         done
8333
8334         local len=${#path}
8335         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8336
8337         test_mkdir $lastdir
8338         cd $lastdir
8339         # PATH_MAX-1
8340         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8341
8342         # NAME_MAX
8343         touch $(str_repeat 'f' 255)
8344
8345         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8346                 error "lfs find reported an error"
8347
8348         rm -rf $DIR/$tdir
8349 }
8350 run_test 56da "test lfs find with long paths"
8351
8352 test_56ea() { #LU-10378
8353         local path=$DIR/$tdir
8354         local pool=$TESTNAME
8355
8356         # Create ost pool
8357         pool_add $pool || error "pool_add $pool failed"
8358         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8359                 error "adding targets to $pool failed"
8360
8361         # Set default pool on directory before creating file
8362         mkdir $path || error "mkdir $path failed"
8363         $LFS setstripe -p $pool $path ||
8364                 error "set OST pool on $pool failed"
8365         touch $path/$tfile || error "touch $path/$tfile failed"
8366
8367         # Compare basic file attributes from -printf and stat
8368         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8369         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8370
8371         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8372                 error "Attrs from lfs find and stat don't match"
8373
8374         # Compare Lustre attributes from lfs find and lfs getstripe
8375         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8376         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8377         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8378         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8379         local fpool=$($LFS getstripe --pool $path/$tfile)
8380         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8381
8382         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8383                 error "Attrs from lfs find and lfs getstripe don't match"
8384
8385         # Verify behavior for unknown escape/format sequences
8386         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8387
8388         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8389                 error "Escape/format codes don't match"
8390 }
8391 run_test 56ea "test lfs find -printf option"
8392
8393 test_57a() {
8394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8395         # note test will not do anything if MDS is not local
8396         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8397                 skip_env "ldiskfs only test"
8398         fi
8399         remote_mds_nodsh && skip "remote MDS with nodsh"
8400
8401         local MNTDEV="osd*.*MDT*.mntdev"
8402         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8403         [ -z "$DEV" ] && error "can't access $MNTDEV"
8404         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8405                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8406                         error "can't access $DEV"
8407                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8408                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8409                 rm $TMP/t57a.dump
8410         done
8411 }
8412 run_test 57a "verify MDS filesystem created with large inodes =="
8413
8414 test_57b() {
8415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8416         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8417                 skip_env "ldiskfs only test"
8418         fi
8419         remote_mds_nodsh && skip "remote MDS with nodsh"
8420
8421         local dir=$DIR/$tdir
8422         local filecount=100
8423         local file1=$dir/f1
8424         local fileN=$dir/f$filecount
8425
8426         rm -rf $dir || error "removing $dir"
8427         test_mkdir -c1 $dir
8428         local mdtidx=$($LFS getstripe -m $dir)
8429         local mdtname=MDT$(printf %04x $mdtidx)
8430         local facet=mds$((mdtidx + 1))
8431
8432         echo "mcreating $filecount files"
8433         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8434
8435         # verify that files do not have EAs yet
8436         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8437                 error "$file1 has an EA"
8438         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8439                 error "$fileN has an EA"
8440
8441         sync
8442         sleep 1
8443         df $dir  #make sure we get new statfs data
8444         local mdsfree=$(do_facet $facet \
8445                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8446         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8447         local file
8448
8449         echo "opening files to create objects/EAs"
8450         for file in $(seq -f $dir/f%g 1 $filecount); do
8451                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8452                         error "opening $file"
8453         done
8454
8455         # verify that files have EAs now
8456         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8457         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8458
8459         sleep 1  #make sure we get new statfs data
8460         df $dir
8461         local mdsfree2=$(do_facet $facet \
8462                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8463         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8464
8465         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8466                 if [ "$mdsfree" != "$mdsfree2" ]; then
8467                         error "MDC before $mdcfree != after $mdcfree2"
8468                 else
8469                         echo "MDC before $mdcfree != after $mdcfree2"
8470                         echo "unable to confirm if MDS has large inodes"
8471                 fi
8472         fi
8473         rm -rf $dir
8474 }
8475 run_test 57b "default LOV EAs are stored inside large inodes ==="
8476
8477 test_58() {
8478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8479         [ -z "$(which wiretest 2>/dev/null)" ] &&
8480                         skip_env "could not find wiretest"
8481
8482         wiretest
8483 }
8484 run_test 58 "verify cross-platform wire constants =============="
8485
8486 test_59() {
8487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8488
8489         echo "touch 130 files"
8490         createmany -o $DIR/f59- 130
8491         echo "rm 130 files"
8492         unlinkmany $DIR/f59- 130
8493         sync
8494         # wait for commitment of removal
8495         wait_delete_completed
8496 }
8497 run_test 59 "verify cancellation of llog records async ========="
8498
8499 TEST60_HEAD="test_60 run $RANDOM"
8500 test_60a() {
8501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8502         remote_mgs_nodsh && skip "remote MGS with nodsh"
8503         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8504                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8505                         skip_env "missing subtest run-llog.sh"
8506
8507         log "$TEST60_HEAD - from kernel mode"
8508         do_facet mgs "$LCTL dk > /dev/null"
8509         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8510         do_facet mgs $LCTL dk > $TMP/$tfile
8511
8512         # LU-6388: test llog_reader
8513         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8514         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8515         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8516                         skip_env "missing llog_reader"
8517         local fstype=$(facet_fstype mgs)
8518         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8519                 skip_env "Only for ldiskfs or zfs type mgs"
8520
8521         local mntpt=$(facet_mntpt mgs)
8522         local mgsdev=$(mgsdevname 1)
8523         local fid_list
8524         local fid
8525         local rec_list
8526         local rec
8527         local rec_type
8528         local obj_file
8529         local path
8530         local seq
8531         local oid
8532         local pass=true
8533
8534         #get fid and record list
8535         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8536                 tail -n 4))
8537         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8538                 tail -n 4))
8539         #remount mgs as ldiskfs or zfs type
8540         stop mgs || error "stop mgs failed"
8541         mount_fstype mgs || error "remount mgs failed"
8542         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8543                 fid=${fid_list[i]}
8544                 rec=${rec_list[i]}
8545                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8546                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8547                 oid=$((16#$oid))
8548
8549                 case $fstype in
8550                         ldiskfs )
8551                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8552                         zfs )
8553                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8554                 esac
8555                 echo "obj_file is $obj_file"
8556                 do_facet mgs $llog_reader $obj_file
8557
8558                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8559                         awk '{ print $3 }' | sed -e "s/^type=//g")
8560                 if [ $rec_type != $rec ]; then
8561                         echo "FAILED test_60a wrong record type $rec_type," \
8562                               "should be $rec"
8563                         pass=false
8564                         break
8565                 fi
8566
8567                 #check obj path if record type is LLOG_LOGID_MAGIC
8568                 if [ "$rec" == "1064553b" ]; then
8569                         path=$(do_facet mgs $llog_reader $obj_file |
8570                                 grep "path=" | awk '{ print $NF }' |
8571                                 sed -e "s/^path=//g")
8572                         if [ $obj_file != $mntpt/$path ]; then
8573                                 echo "FAILED test_60a wrong obj path" \
8574                                       "$montpt/$path, should be $obj_file"
8575                                 pass=false
8576                                 break
8577                         fi
8578                 fi
8579         done
8580         rm -f $TMP/$tfile
8581         #restart mgs before "error", otherwise it will block the next test
8582         stop mgs || error "stop mgs failed"
8583         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8584         $pass || error "test failed, see FAILED test_60a messages for specifics"
8585 }
8586 run_test 60a "llog_test run from kernel module and test llog_reader"
8587
8588 test_60b() { # bug 6411
8589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8590
8591         dmesg > $DIR/$tfile
8592         LLOG_COUNT=$(do_facet mgs dmesg |
8593                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8594                           /llog_[a-z]*.c:[0-9]/ {
8595                                 if (marker)
8596                                         from_marker++
8597                                 from_begin++
8598                           }
8599                           END {
8600                                 if (marker)
8601                                         print from_marker
8602                                 else
8603                                         print from_begin
8604                           }")
8605
8606         [[ $LLOG_COUNT -gt 120 ]] &&
8607                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8608 }
8609 run_test 60b "limit repeated messages from CERROR/CWARN"
8610
8611 test_60c() {
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613
8614         echo "create 5000 files"
8615         createmany -o $DIR/f60c- 5000
8616 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8617         lctl set_param fail_loc=0x80000137
8618         unlinkmany $DIR/f60c- 5000
8619         lctl set_param fail_loc=0
8620 }
8621 run_test 60c "unlink file when mds full"
8622
8623 test_60d() {
8624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8625
8626         SAVEPRINTK=$(lctl get_param -n printk)
8627         # verify "lctl mark" is even working"
8628         MESSAGE="test message ID $RANDOM $$"
8629         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8630         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8631
8632         lctl set_param printk=0 || error "set lnet.printk failed"
8633         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8634         MESSAGE="new test message ID $RANDOM $$"
8635         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8636         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8637         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8638
8639         lctl set_param -n printk="$SAVEPRINTK"
8640 }
8641 run_test 60d "test printk console message masking"
8642
8643 test_60e() {
8644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8645         remote_mds_nodsh && skip "remote MDS with nodsh"
8646
8647         touch $DIR/$tfile
8648 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8649         do_facet mds1 lctl set_param fail_loc=0x15b
8650         rm $DIR/$tfile
8651 }
8652 run_test 60e "no space while new llog is being created"
8653
8654 test_60f() {
8655         local old_path=$($LCTL get_param -n debug_path)
8656
8657         stack_trap "$LCTL set_param debug_path=$old_path"
8658         stack_trap "rm -f $TMP/$tfile*"
8659         rm -f $TMP/$tfile* 2> /dev/null
8660         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8661         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8662         test_mkdir $DIR/$tdir
8663         # retry in case the open is cached and not released
8664         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8665                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8666                 sleep 0.1
8667         done
8668         ls $TMP/$tfile*
8669         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8670 }
8671 run_test 60f "change debug_path works"
8672
8673 test_60g() {
8674         local pid
8675         local i
8676
8677         test_mkdir -c $MDSCOUNT $DIR/$tdir
8678
8679         (
8680                 local index=0
8681                 while true; do
8682                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8683                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8684                                 2>/dev/null
8685                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8686                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8687                         index=$((index + 1))
8688                 done
8689         ) &
8690
8691         pid=$!
8692
8693         for i in {0..100}; do
8694                 # define OBD_FAIL_OSD_TXN_START    0x19a
8695                 local index=$((i % MDSCOUNT + 1))
8696
8697                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8698                         > /dev/null
8699                 sleep 0.01
8700         done
8701
8702         kill -9 $pid
8703
8704         for i in $(seq $MDSCOUNT); do
8705                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8706         done
8707
8708         mkdir $DIR/$tdir/new || error "mkdir failed"
8709         rmdir $DIR/$tdir/new || error "rmdir failed"
8710
8711         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8712                 -t namespace
8713         for i in $(seq $MDSCOUNT); do
8714                 wait_update_facet mds$i "$LCTL get_param -n \
8715                         mdd.$(facet_svc mds$i).lfsck_namespace |
8716                         awk '/^status/ { print \\\$2 }'" "completed"
8717         done
8718
8719         ls -R $DIR/$tdir
8720         rm -rf $DIR/$tdir || error "rmdir failed"
8721 }
8722 run_test 60g "transaction abort won't cause MDT hung"
8723
8724 test_60h() {
8725         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8726                 skip "Need MDS version at least 2.12.52"
8727         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8728
8729         local f
8730
8731         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8732         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8733         for fail_loc in 0x80000188 0x80000189; do
8734                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8735                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8736                         error "mkdir $dir-$fail_loc failed"
8737                 for i in {0..10}; do
8738                         # create may fail on missing stripe
8739                         echo $i > $DIR/$tdir-$fail_loc/$i
8740                 done
8741                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8742                         error "getdirstripe $tdir-$fail_loc failed"
8743                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8744                         error "migrate $tdir-$fail_loc failed"
8745                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8746                         error "getdirstripe $tdir-$fail_loc failed"
8747                 pushd $DIR/$tdir-$fail_loc
8748                 for f in *; do
8749                         echo $f | cmp $f - || error "$f data mismatch"
8750                 done
8751                 popd
8752                 rm -rf $DIR/$tdir-$fail_loc
8753         done
8754 }
8755 run_test 60h "striped directory with missing stripes can be accessed"
8756
8757 function t60i_load() {
8758         mkdir $DIR/$tdir
8759         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8760         $LCTL set_param fail_loc=0x131c fail_val=1
8761         for ((i=0; i<5000; i++)); do
8762                 touch $DIR/$tdir/f$i
8763         done
8764 }
8765
8766 test_60i() {
8767         changelog_register || error "changelog_register failed"
8768         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8769         changelog_users $SINGLEMDS | grep -q $cl_user ||
8770                 error "User $cl_user not found in changelog_users"
8771         changelog_chmask "ALL"
8772         t60i_load &
8773         local PID=$!
8774         for((i=0; i<100; i++)); do
8775                 changelog_dump >/dev/null ||
8776                         error "can't read changelog"
8777         done
8778         kill $PID
8779         wait $PID
8780         changelog_deregister || error "changelog_deregister failed"
8781         $LCTL set_param fail_loc=0
8782 }
8783 run_test 60i "llog: new record vs reader race"
8784
8785 test_61a() {
8786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8787
8788         f="$DIR/f61"
8789         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8790         cancel_lru_locks osc
8791         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8792         sync
8793 }
8794 run_test 61a "mmap() writes don't make sync hang ================"
8795
8796 test_61b() {
8797         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8798 }
8799 run_test 61b "mmap() of unstriped file is successful"
8800
8801 # bug 2330 - insufficient obd_match error checking causes LBUG
8802 test_62() {
8803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8804
8805         f="$DIR/f62"
8806         echo foo > $f
8807         cancel_lru_locks osc
8808         lctl set_param fail_loc=0x405
8809         cat $f && error "cat succeeded, expect -EIO"
8810         lctl set_param fail_loc=0
8811 }
8812 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8813 # match every page all of the time.
8814 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8815
8816 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8817 # Though this test is irrelevant anymore, it helped to reveal some
8818 # other grant bugs (LU-4482), let's keep it.
8819 test_63a() {   # was test_63
8820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8821
8822         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8823
8824         for i in `seq 10` ; do
8825                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8826                 sleep 5
8827                 kill $!
8828                 sleep 1
8829         done
8830
8831         rm -f $DIR/f63 || true
8832 }
8833 run_test 63a "Verify oig_wait interruption does not crash ======="
8834
8835 # bug 2248 - async write errors didn't return to application on sync
8836 # bug 3677 - async write errors left page locked
8837 test_63b() {
8838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8839
8840         debugsave
8841         lctl set_param debug=-1
8842
8843         # ensure we have a grant to do async writes
8844         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8845         rm $DIR/$tfile
8846
8847         sync    # sync lest earlier test intercept the fail_loc
8848
8849         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8850         lctl set_param fail_loc=0x80000406
8851         $MULTIOP $DIR/$tfile Owy && \
8852                 error "sync didn't return ENOMEM"
8853         sync; sleep 2; sync     # do a real sync this time to flush page
8854         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8855                 error "locked page left in cache after async error" || true
8856         debugrestore
8857 }
8858 run_test 63b "async write errors should be returned to fsync ==="
8859
8860 test_64a () {
8861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8862
8863         lfs df $DIR
8864         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8865 }
8866 run_test 64a "verify filter grant calculations (in kernel) ====="
8867
8868 test_64b () {
8869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8870
8871         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8872 }
8873 run_test 64b "check out-of-space detection on client"
8874
8875 test_64c() {
8876         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8877 }
8878 run_test 64c "verify grant shrink"
8879
8880 import_param() {
8881         local tgt=$1
8882         local param=$2
8883
8884         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8885 }
8886
8887 # this does exactly what osc_request.c:osc_announce_cached() does in
8888 # order to calculate max amount of grants to ask from server
8889 want_grant() {
8890         local tgt=$1
8891
8892         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8893         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8894
8895         ((rpc_in_flight++));
8896         nrpages=$((nrpages * rpc_in_flight))
8897
8898         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8899
8900         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8901
8902         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8903         local undirty=$((nrpages * PAGE_SIZE))
8904
8905         local max_extent_pages
8906         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8907         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8908         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8909         local grant_extent_tax
8910         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8911
8912         undirty=$((undirty + nrextents * grant_extent_tax))
8913
8914         echo $undirty
8915 }
8916
8917 # this is size of unit for grant allocation. It should be equal to
8918 # what tgt_grant.c:tgt_grant_chunk() calculates
8919 grant_chunk() {
8920         local tgt=$1
8921         local max_brw_size
8922         local grant_extent_tax
8923
8924         max_brw_size=$(import_param $tgt max_brw_size)
8925
8926         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8927
8928         echo $(((max_brw_size + grant_extent_tax) * 2))
8929 }
8930
8931 test_64d() {
8932         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8933                 skip "OST < 2.10.55 doesn't limit grants enough"
8934
8935         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8936
8937         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8938                 skip "no grant_param connect flag"
8939
8940         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8941
8942         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8943         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8944
8945
8946         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8947         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8948
8949         $LFS setstripe $DIR/$tfile -i 0 -c 1
8950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8951         ddpid=$!
8952
8953         while kill -0 $ddpid; do
8954                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8955
8956                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8957                         kill $ddpid
8958                         error "cur_grant $cur_grant > $max_cur_granted"
8959                 fi
8960
8961                 sleep 1
8962         done
8963 }
8964 run_test 64d "check grant limit exceed"
8965
8966 check_grants() {
8967         local tgt=$1
8968         local expected=$2
8969         local msg=$3
8970         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8971
8972         ((cur_grants == expected)) ||
8973                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8974 }
8975
8976 round_up_p2() {
8977         echo $((($1 + $2 - 1) & ~($2 - 1)))
8978 }
8979
8980 test_64e() {
8981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8982         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8983                 skip "Need OSS version at least 2.11.56"
8984
8985         # Remount client to reset grant
8986         remount_client $MOUNT || error "failed to remount client"
8987         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8988
8989         local init_grants=$(import_param $osc_tgt initial_grant)
8990
8991         check_grants $osc_tgt $init_grants "init grants"
8992
8993         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8994         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8995         local gbs=$(import_param $osc_tgt grant_block_size)
8996
8997         # write random number of bytes from max_brw_size / 4 to max_brw_size
8998         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8999         # align for direct io
9000         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9001         # round to grant consumption unit
9002         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9003
9004         local grants=$((wb_round_up + extent_tax))
9005
9006         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9007
9008         # define OBD_FAIL_TGT_NO_GRANT 0x725
9009         # make the server not grant more back
9010         do_facet ost1 $LCTL set_param fail_loc=0x725
9011         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9012
9013         do_facet ost1 $LCTL set_param fail_loc=0
9014
9015         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9016
9017         rm -f $DIR/$tfile || error "rm failed"
9018
9019         # Remount client to reset grant
9020         remount_client $MOUNT || error "failed to remount client"
9021         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9022
9023         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9024
9025         # define OBD_FAIL_TGT_NO_GRANT 0x725
9026         # make the server not grant more back
9027         do_facet ost1 $LCTL set_param fail_loc=0x725
9028         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9029         do_facet ost1 $LCTL set_param fail_loc=0
9030
9031         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9032 }
9033 run_test 64e "check grant consumption (no grant allocation)"
9034
9035 test_64f() {
9036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9037
9038         # Remount client to reset grant
9039         remount_client $MOUNT || error "failed to remount client"
9040         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9041
9042         local init_grants=$(import_param $osc_tgt initial_grant)
9043         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9044         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9045         local gbs=$(import_param $osc_tgt grant_block_size)
9046         local chunk=$(grant_chunk $osc_tgt)
9047
9048         # write random number of bytes from max_brw_size / 4 to max_brw_size
9049         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9050         # align for direct io
9051         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9052         # round to grant consumption unit
9053         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9054
9055         local grants=$((wb_round_up + extent_tax))
9056
9057         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9058         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9059                 error "error writing to $DIR/$tfile"
9060
9061         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9062                 "direct io with grant allocation"
9063
9064         rm -f $DIR/$tfile || error "rm failed"
9065
9066         # Remount client to reset grant
9067         remount_client $MOUNT || error "failed to remount client"
9068         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9069
9070         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9071
9072         local cmd="oO_WRONLY:w${write_bytes}_yc"
9073
9074         $MULTIOP $DIR/$tfile $cmd &
9075         MULTIPID=$!
9076         sleep 1
9077
9078         check_grants $osc_tgt $((init_grants - grants)) \
9079                 "buffered io, not write rpc"
9080
9081         kill -USR1 $MULTIPID
9082         wait
9083
9084         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9085                 "buffered io, one RPC"
9086 }
9087 run_test 64f "check grant consumption (with grant allocation)"
9088
9089 test_64g() {
9090         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9091                 skip "Need MDS version at least 2.14.56"
9092
9093         local mdts=$(comma_list $(mdts_nodes))
9094
9095         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9096                         tr '\n' ' ')
9097         stack_trap "$LCTL set_param $old"
9098
9099         # generate dirty pages and increase dirty granted on MDT
9100         stack_trap "rm -f $DIR/$tfile-*"
9101         for (( i = 0; i < 10; i++)); do
9102                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9103                         error "can't set stripe"
9104                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9105                         error "can't dd"
9106                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9107                         $LFS getstripe $DIR/$tfile-$i
9108                         error "not DoM file"
9109                 }
9110         done
9111
9112         # flush dirty pages
9113         sync
9114
9115         # wait until grant shrink reset grant dirty on MDTs
9116         for ((i = 0; i < 120; i++)); do
9117                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9118                         awk '{sum=sum+$1} END {print sum}')
9119                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9120                 echo "$grant_dirty grants, $vm_dirty pages"
9121                 (( grant_dirty + vm_dirty == 0 )) && break
9122                 (( i == 3 )) && sync &&
9123                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9124                 sleep 1
9125         done
9126
9127         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9128                 awk '{sum=sum+$1} END {print sum}')
9129         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9130 }
9131 run_test 64g "grant shrink on MDT"
9132
9133 test_64h() {
9134         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9135                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9136
9137         local instance=$($LFS getname -i $DIR)
9138         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9139         local num_exps=$(do_facet ost1 \
9140             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9141         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9142         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9143         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9144
9145         # 10MiB is for file to be written, max_brw_size * 16 *
9146         # num_exps is space reserve so that tgt_grant_shrink() decided
9147         # to not shrink
9148         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9149         (( avail * 1024 < expect )) &&
9150                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9151
9152         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9153         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9154         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9155         $LCTL set_param osc.*OST0000*.grant_shrink=1
9156         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9157
9158         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9159         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9160
9161         # drop cache so that coming read would do rpc
9162         cancel_lru_locks osc
9163
9164         # shrink interval is set to 10, pause for 7 seconds so that
9165         # grant thread did not wake up yet but coming read entered
9166         # shrink mode for rpc (osc_should_shrink_grant())
9167         sleep 7
9168
9169         declare -a cur_grant_bytes
9170         declare -a tot_granted
9171         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9172         tot_granted[0]=$(do_facet ost1 \
9173             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9174
9175         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9176
9177         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9178         tot_granted[1]=$(do_facet ost1 \
9179             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9180
9181         # grant change should be equal on both sides
9182         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9183                 tot_granted[0] - tot_granted[1])) ||
9184                 error "grant change mismatch, "                                \
9185                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9186                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9187 }
9188 run_test 64h "grant shrink on read"
9189
9190 test_64i() {
9191         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9192                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9193
9194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9195         remote_ost_nodsh && skip "remote OSTs with nodsh"
9196
9197         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9198
9199         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9200
9201         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9202         local instance=$($LFS getname -i $DIR)
9203
9204         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9205         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9206
9207         # shrink grants and simulate rpc loss
9208         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9209         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9210         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9211
9212         fail ost1
9213
9214         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9215
9216         local testid=$(echo $TESTNAME | tr '_' ' ')
9217
9218         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9219                 grep "GRANT, real grant" &&
9220                 error "client has more grants then it owns" || true
9221 }
9222 run_test 64i "shrink on reconnect"
9223
9224 # bug 1414 - set/get directories' stripe info
9225 test_65a() {
9226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9227
9228         test_mkdir $DIR/$tdir
9229         touch $DIR/$tdir/f1
9230         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9231 }
9232 run_test 65a "directory with no stripe info"
9233
9234 test_65b() {
9235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9236
9237         test_mkdir $DIR/$tdir
9238         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9239
9240         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9241                                                 error "setstripe"
9242         touch $DIR/$tdir/f2
9243         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9244 }
9245 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9246
9247 test_65c() {
9248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9249         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9250
9251         test_mkdir $DIR/$tdir
9252         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9253
9254         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9255                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9256         touch $DIR/$tdir/f3
9257         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9258 }
9259 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9260
9261 test_65d() {
9262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9263
9264         test_mkdir $DIR/$tdir
9265         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9266         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9267
9268         if [[ $STRIPECOUNT -le 0 ]]; then
9269                 sc=1
9270         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9271                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9272                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9273         else
9274                 sc=$(($STRIPECOUNT - 1))
9275         fi
9276         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9277         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9278         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9279                 error "lverify failed"
9280 }
9281 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9282
9283 test_65e() {
9284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9285
9286         test_mkdir $DIR/$tdir
9287
9288         $LFS setstripe $DIR/$tdir || error "setstripe"
9289         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9290                                         error "no stripe info failed"
9291         touch $DIR/$tdir/f6
9292         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9293 }
9294 run_test 65e "directory setstripe defaults"
9295
9296 test_65f() {
9297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9298
9299         test_mkdir $DIR/${tdir}f
9300         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9301                 error "setstripe succeeded" || true
9302 }
9303 run_test 65f "dir setstripe permission (should return error) ==="
9304
9305 test_65g() {
9306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9307
9308         test_mkdir $DIR/$tdir
9309         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9310
9311         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9312                 error "setstripe -S failed"
9313         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9314         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9315                 error "delete default stripe failed"
9316 }
9317 run_test 65g "directory setstripe -d"
9318
9319 test_65h() {
9320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9321
9322         test_mkdir $DIR/$tdir
9323         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9324
9325         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9326                 error "setstripe -S failed"
9327         test_mkdir $DIR/$tdir/dd1
9328         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9329                 error "stripe info inherit failed"
9330 }
9331 run_test 65h "directory stripe info inherit ===================="
9332
9333 test_65i() {
9334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9335
9336         save_layout_restore_at_exit $MOUNT
9337
9338         # bug6367: set non-default striping on root directory
9339         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9340
9341         # bug12836: getstripe on -1 default directory striping
9342         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9343
9344         # bug12836: getstripe -v on -1 default directory striping
9345         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9346
9347         # bug12836: new find on -1 default directory striping
9348         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9349 }
9350 run_test 65i "various tests to set root directory striping"
9351
9352 test_65j() { # bug6367
9353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9354
9355         sync; sleep 1
9356
9357         # if we aren't already remounting for each test, do so for this test
9358         if [ "$I_MOUNTED" = "yes" ]; then
9359                 cleanup || error "failed to unmount"
9360                 setup
9361         fi
9362
9363         save_layout_restore_at_exit $MOUNT
9364
9365         $LFS setstripe -d $MOUNT || error "setstripe failed"
9366 }
9367 run_test 65j "set default striping on root directory (bug 6367)="
9368
9369 cleanup_65k() {
9370         rm -rf $DIR/$tdir
9371         wait_delete_completed
9372         do_facet $SINGLEMDS "lctl set_param -n \
9373                 osp.$ost*MDT0000.max_create_count=$max_count"
9374         do_facet $SINGLEMDS "lctl set_param -n \
9375                 osp.$ost*MDT0000.create_count=$count"
9376         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9377         echo $INACTIVE_OSC "is Activate"
9378
9379         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9380 }
9381
9382 test_65k() { # bug11679
9383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9384         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9385         remote_mds_nodsh && skip "remote MDS with nodsh"
9386
9387         local disable_precreate=true
9388         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9389                 disable_precreate=false
9390
9391         echo "Check OST status: "
9392         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9393                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9394
9395         for OSC in $MDS_OSCS; do
9396                 echo $OSC "is active"
9397                 do_facet $SINGLEMDS lctl --device %$OSC activate
9398         done
9399
9400         for INACTIVE_OSC in $MDS_OSCS; do
9401                 local ost=$(osc_to_ost $INACTIVE_OSC)
9402                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9403                                lov.*md*.target_obd |
9404                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9405
9406                 mkdir -p $DIR/$tdir
9407                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9408                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9409
9410                 echo "Deactivate: " $INACTIVE_OSC
9411                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9412
9413                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9414                               osp.$ost*MDT0000.create_count")
9415                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9416                                   osp.$ost*MDT0000.max_create_count")
9417                 $disable_precreate &&
9418                         do_facet $SINGLEMDS "lctl set_param -n \
9419                                 osp.$ost*MDT0000.max_create_count=0"
9420
9421                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9422                         [ -f $DIR/$tdir/$idx ] && continue
9423                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9424                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9425                                 { cleanup_65k;
9426                                   error "setstripe $idx should succeed"; }
9427                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9428                 done
9429                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9430                 rmdir $DIR/$tdir
9431
9432                 do_facet $SINGLEMDS "lctl set_param -n \
9433                         osp.$ost*MDT0000.max_create_count=$max_count"
9434                 do_facet $SINGLEMDS "lctl set_param -n \
9435                         osp.$ost*MDT0000.create_count=$count"
9436                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9437                 echo $INACTIVE_OSC "is Activate"
9438
9439                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9440         done
9441 }
9442 run_test 65k "validate manual striping works properly with deactivated OSCs"
9443
9444 test_65l() { # bug 12836
9445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9446
9447         test_mkdir -p $DIR/$tdir/test_dir
9448         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9449         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9450 }
9451 run_test 65l "lfs find on -1 stripe dir ========================"
9452
9453 test_65m() {
9454         local layout=$(save_layout $MOUNT)
9455         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9456                 restore_layout $MOUNT $layout
9457                 error "setstripe should fail by non-root users"
9458         }
9459         true
9460 }
9461 run_test 65m "normal user can't set filesystem default stripe"
9462
9463 test_65n() {
9464         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9465         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9466                 skip "Need MDS version at least 2.12.50"
9467         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9468
9469         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9470         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9471         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9472
9473         save_layout_restore_at_exit $MOUNT
9474
9475         # new subdirectory under root directory should not inherit
9476         # the default layout from root
9477         local dir1=$MOUNT/$tdir-1
9478         mkdir $dir1 || error "mkdir $dir1 failed"
9479         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9480                 error "$dir1 shouldn't have LOV EA"
9481
9482         # delete the default layout on root directory
9483         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9484
9485         local dir2=$MOUNT/$tdir-2
9486         mkdir $dir2 || error "mkdir $dir2 failed"
9487         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9488                 error "$dir2 shouldn't have LOV EA"
9489
9490         # set a new striping pattern on root directory
9491         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9492         local new_def_stripe_size=$((def_stripe_size * 2))
9493         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9494                 error "set stripe size on $MOUNT failed"
9495
9496         # new file created in $dir2 should inherit the new stripe size from
9497         # the filesystem default
9498         local file2=$dir2/$tfile-2
9499         touch $file2 || error "touch $file2 failed"
9500
9501         local file2_stripe_size=$($LFS getstripe -S $file2)
9502         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9503         {
9504                 echo "file2_stripe_size: '$file2_stripe_size'"
9505                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9506                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9507         }
9508
9509         local dir3=$MOUNT/$tdir-3
9510         mkdir $dir3 || error "mkdir $dir3 failed"
9511         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9512         # the root layout, which is the actual default layout that will be used
9513         # when new files are created in $dir3.
9514         local dir3_layout=$(get_layout_param $dir3)
9515         local root_dir_layout=$(get_layout_param $MOUNT)
9516         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9517         {
9518                 echo "dir3_layout: '$dir3_layout'"
9519                 echo "root_dir_layout: '$root_dir_layout'"
9520                 error "$dir3 should show the default layout from $MOUNT"
9521         }
9522
9523         # set OST pool on root directory
9524         local pool=$TESTNAME
9525         pool_add $pool || error "add $pool failed"
9526         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9527                 error "add targets to $pool failed"
9528
9529         $LFS setstripe -p $pool $MOUNT ||
9530                 error "set OST pool on $MOUNT failed"
9531
9532         # new file created in $dir3 should inherit the pool from
9533         # the filesystem default
9534         local file3=$dir3/$tfile-3
9535         touch $file3 || error "touch $file3 failed"
9536
9537         local file3_pool=$($LFS getstripe -p $file3)
9538         [[ "$file3_pool" = "$pool" ]] ||
9539                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9540
9541         local dir4=$MOUNT/$tdir-4
9542         mkdir $dir4 || error "mkdir $dir4 failed"
9543         local dir4_layout=$(get_layout_param $dir4)
9544         root_dir_layout=$(get_layout_param $MOUNT)
9545         echo "$LFS getstripe -d $dir4"
9546         $LFS getstripe -d $dir4
9547         echo "$LFS getstripe -d $MOUNT"
9548         $LFS getstripe -d $MOUNT
9549         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9550         {
9551                 echo "dir4_layout: '$dir4_layout'"
9552                 echo "root_dir_layout: '$root_dir_layout'"
9553                 error "$dir4 should show the default layout from $MOUNT"
9554         }
9555
9556         # new file created in $dir4 should inherit the pool from
9557         # the filesystem default
9558         local file4=$dir4/$tfile-4
9559         touch $file4 || error "touch $file4 failed"
9560
9561         local file4_pool=$($LFS getstripe -p $file4)
9562         [[ "$file4_pool" = "$pool" ]] ||
9563                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9564
9565         # new subdirectory under non-root directory should inherit
9566         # the default layout from its parent directory
9567         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9568                 error "set directory layout on $dir4 failed"
9569
9570         local dir5=$dir4/$tdir-5
9571         mkdir $dir5 || error "mkdir $dir5 failed"
9572
9573         dir4_layout=$(get_layout_param $dir4)
9574         local dir5_layout=$(get_layout_param $dir5)
9575         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9576         {
9577                 echo "dir4_layout: '$dir4_layout'"
9578                 echo "dir5_layout: '$dir5_layout'"
9579                 error "$dir5 should inherit the default layout from $dir4"
9580         }
9581
9582         # though subdir under ROOT doesn't inherit default layout, but
9583         # its sub dir/file should be created with default layout.
9584         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9585         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9586                 skip "Need MDS version at least 2.12.59"
9587
9588         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9589         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9590         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9591
9592         if [ $default_lmv_hash == "none" ]; then
9593                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9594         else
9595                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9596                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9597         fi
9598
9599         $LFS setdirstripe -D -c 2 $MOUNT ||
9600                 error "setdirstripe -D -c 2 failed"
9601         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9602         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9603         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9604
9605         # $dir4 layout includes pool
9606         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9607         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9608                 error "pool lost on setstripe"
9609         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9610         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9611                 error "pool lost on compound layout setstripe"
9612 }
9613 run_test 65n "don't inherit default layout from root for new subdirectories"
9614
9615 # bug 2543 - update blocks count on client
9616 test_66() {
9617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9618
9619         COUNT=${COUNT:-8}
9620         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9621         sync; sync_all_data; sync; sync_all_data
9622         cancel_lru_locks osc
9623         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9624         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9625 }
9626 run_test 66 "update inode blocks count on client ==============="
9627
9628 meminfo() {
9629         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9630 }
9631
9632 swap_used() {
9633         swapon -s | awk '($1 == "'$1'") { print $4 }'
9634 }
9635
9636 # bug5265, obdfilter oa2dentry return -ENOENT
9637 # #define OBD_FAIL_SRV_ENOENT 0x217
9638 test_69() {
9639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9640         remote_ost_nodsh && skip "remote OST with nodsh"
9641
9642         f="$DIR/$tfile"
9643         $LFS setstripe -c 1 -i 0 $f
9644
9645         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9646
9647         do_facet ost1 lctl set_param fail_loc=0x217
9648         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9649         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9650
9651         do_facet ost1 lctl set_param fail_loc=0
9652         $DIRECTIO write $f 0 2 || error "write error"
9653
9654         cancel_lru_locks osc
9655         $DIRECTIO read $f 0 1 || error "read error"
9656
9657         do_facet ost1 lctl set_param fail_loc=0x217
9658         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9659
9660         do_facet ost1 lctl set_param fail_loc=0
9661         rm -f $f
9662 }
9663 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9664
9665 test_71() {
9666         test_mkdir $DIR/$tdir
9667         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9668         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9669 }
9670 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9671
9672 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9674         [ "$RUNAS_ID" = "$UID" ] &&
9675                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9676         # Check that testing environment is properly set up. Skip if not
9677         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9678                 skip_env "User $RUNAS_ID does not exist - skipping"
9679
9680         touch $DIR/$tfile
9681         chmod 777 $DIR/$tfile
9682         chmod ug+s $DIR/$tfile
9683         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9684                 error "$RUNAS dd $DIR/$tfile failed"
9685         # See if we are still setuid/sgid
9686         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9687                 error "S/gid is not dropped on write"
9688         # Now test that MDS is updated too
9689         cancel_lru_locks mdc
9690         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9691                 error "S/gid is not dropped on MDS"
9692         rm -f $DIR/$tfile
9693 }
9694 run_test 72a "Test that remove suid works properly (bug5695) ===="
9695
9696 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9697         local perm
9698
9699         [ "$RUNAS_ID" = "$UID" ] &&
9700                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9701         [ "$RUNAS_ID" -eq 0 ] &&
9702                 skip_env "RUNAS_ID = 0 -- skipping"
9703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9704         # Check that testing environment is properly set up. Skip if not
9705         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9706                 skip_env "User $RUNAS_ID does not exist - skipping"
9707
9708         touch $DIR/${tfile}-f{g,u}
9709         test_mkdir $DIR/${tfile}-dg
9710         test_mkdir $DIR/${tfile}-du
9711         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9712         chmod g+s $DIR/${tfile}-{f,d}g
9713         chmod u+s $DIR/${tfile}-{f,d}u
9714         for perm in 777 2777 4777; do
9715                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9716                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9717                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9718                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9719         done
9720         true
9721 }
9722 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9723
9724 # bug 3462 - multiple simultaneous MDC requests
9725 test_73() {
9726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9727
9728         test_mkdir $DIR/d73-1
9729         test_mkdir $DIR/d73-2
9730         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9731         pid1=$!
9732
9733         lctl set_param fail_loc=0x80000129
9734         $MULTIOP $DIR/d73-1/f73-2 Oc &
9735         sleep 1
9736         lctl set_param fail_loc=0
9737
9738         $MULTIOP $DIR/d73-2/f73-3 Oc &
9739         pid3=$!
9740
9741         kill -USR1 $pid1
9742         wait $pid1 || return 1
9743
9744         sleep 25
9745
9746         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9747         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9748         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9749
9750         rm -rf $DIR/d73-*
9751 }
9752 run_test 73 "multiple MDC requests (should not deadlock)"
9753
9754 test_74a() { # bug 6149, 6184
9755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9756
9757         touch $DIR/f74a
9758         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9759         #
9760         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9761         # will spin in a tight reconnection loop
9762         $LCTL set_param fail_loc=0x8000030e
9763         # get any lock that won't be difficult - lookup works.
9764         ls $DIR/f74a
9765         $LCTL set_param fail_loc=0
9766         rm -f $DIR/f74a
9767         true
9768 }
9769 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9770
9771 test_74b() { # bug 13310
9772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9773
9774         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9775         #
9776         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9777         # will spin in a tight reconnection loop
9778         $LCTL set_param fail_loc=0x8000030e
9779         # get a "difficult" lock
9780         touch $DIR/f74b
9781         $LCTL set_param fail_loc=0
9782         rm -f $DIR/f74b
9783         true
9784 }
9785 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9786
9787 test_74c() {
9788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9789
9790         #define OBD_FAIL_LDLM_NEW_LOCK
9791         $LCTL set_param fail_loc=0x319
9792         touch $DIR/$tfile && error "touch successful"
9793         $LCTL set_param fail_loc=0
9794         true
9795 }
9796 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9797
9798 slab_lic=/sys/kernel/slab/lustre_inode_cache
9799 num_objects() {
9800         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9801         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9802                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9803 }
9804
9805 test_76a() { # Now for b=20433, added originally in b=1443
9806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9807
9808         cancel_lru_locks osc
9809         # there may be some slab objects cached per core
9810         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9811         local before=$(num_objects)
9812         local count=$((512 * cpus))
9813         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9814         local margin=$((count / 10))
9815         if [[ -f $slab_lic/aliases ]]; then
9816                 local aliases=$(cat $slab_lic/aliases)
9817                 (( aliases > 0 )) && margin=$((margin * aliases))
9818         fi
9819
9820         echo "before slab objects: $before"
9821         for i in $(seq $count); do
9822                 touch $DIR/$tfile
9823                 rm -f $DIR/$tfile
9824         done
9825         cancel_lru_locks osc
9826         local after=$(num_objects)
9827         echo "created: $count, after slab objects: $after"
9828         # shared slab counts are not very accurate, allow significant margin
9829         # the main goal is that the cache growth is not permanently > $count
9830         while (( after > before + margin )); do
9831                 sleep 1
9832                 after=$(num_objects)
9833                 wait=$((wait + 1))
9834                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9835                 if (( wait > 60 )); then
9836                         error "inode slab grew from $before+$margin to $after"
9837                 fi
9838         done
9839 }
9840 run_test 76a "confirm clients recycle inodes properly ===="
9841
9842 test_76b() {
9843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9844         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9845
9846         local count=512
9847         local before=$(num_objects)
9848
9849         for i in $(seq $count); do
9850                 mkdir $DIR/$tdir
9851                 rmdir $DIR/$tdir
9852         done
9853
9854         local after=$(num_objects)
9855         local wait=0
9856
9857         while (( after > before )); do
9858                 sleep 1
9859                 after=$(num_objects)
9860                 wait=$((wait + 1))
9861                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9862                 if (( wait > 60 )); then
9863                         error "inode slab grew from $before to $after"
9864                 fi
9865         done
9866
9867         echo "slab objects before: $before, after: $after"
9868 }
9869 run_test 76b "confirm clients recycle directory inodes properly ===="
9870
9871 export ORIG_CSUM=""
9872 set_checksums()
9873 {
9874         # Note: in sptlrpc modes which enable its own bulk checksum, the
9875         # original crc32_le bulk checksum will be automatically disabled,
9876         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9877         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9878         # In this case set_checksums() will not be no-op, because sptlrpc
9879         # bulk checksum will be enabled all through the test.
9880
9881         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9882         lctl set_param -n osc.*.checksums $1
9883         return 0
9884 }
9885
9886 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9887                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9888 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9889                              tr -d [] | head -n1)}
9890 set_checksum_type()
9891 {
9892         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9893         rc=$?
9894         log "set checksum type to $1, rc = $rc"
9895         return $rc
9896 }
9897
9898 get_osc_checksum_type()
9899 {
9900         # arugment 1: OST name, like OST0000
9901         ost=$1
9902         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9903                         sed 's/.*\[\(.*\)\].*/\1/g')
9904         rc=$?
9905         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9906         echo $checksum_type
9907 }
9908
9909 F77_TMP=$TMP/f77-temp
9910 F77SZ=8
9911 setup_f77() {
9912         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9913                 error "error writing to $F77_TMP"
9914 }
9915
9916 test_77a() { # bug 10889
9917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9918         $GSS && skip_env "could not run with gss"
9919
9920         [ ! -f $F77_TMP ] && setup_f77
9921         set_checksums 1
9922         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9923         set_checksums 0
9924         rm -f $DIR/$tfile
9925 }
9926 run_test 77a "normal checksum read/write operation"
9927
9928 test_77b() { # bug 10889
9929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9930         $GSS && skip_env "could not run with gss"
9931
9932         [ ! -f $F77_TMP ] && setup_f77
9933         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9934         $LCTL set_param fail_loc=0x80000409
9935         set_checksums 1
9936
9937         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9938                 error "dd error: $?"
9939         $LCTL set_param fail_loc=0
9940
9941         for algo in $CKSUM_TYPES; do
9942                 cancel_lru_locks osc
9943                 set_checksum_type $algo
9944                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9945                 $LCTL set_param fail_loc=0x80000408
9946                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9947                 $LCTL set_param fail_loc=0
9948         done
9949         set_checksums 0
9950         set_checksum_type $ORIG_CSUM_TYPE
9951         rm -f $DIR/$tfile
9952 }
9953 run_test 77b "checksum error on client write, read"
9954
9955 cleanup_77c() {
9956         trap 0
9957         set_checksums 0
9958         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9959         $check_ost &&
9960                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9961         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9962         $check_ost && [ -n "$ost_file_prefix" ] &&
9963                 do_facet ost1 rm -f ${ost_file_prefix}\*
9964 }
9965
9966 test_77c() {
9967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9968         $GSS && skip_env "could not run with gss"
9969         remote_ost_nodsh && skip "remote OST with nodsh"
9970
9971         local bad1
9972         local osc_file_prefix
9973         local osc_file
9974         local check_ost=false
9975         local ost_file_prefix
9976         local ost_file
9977         local orig_cksum
9978         local dump_cksum
9979         local fid
9980
9981         # ensure corruption will occur on first OSS/OST
9982         $LFS setstripe -i 0 $DIR/$tfile
9983
9984         [ ! -f $F77_TMP ] && setup_f77
9985         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9986                 error "dd write error: $?"
9987         fid=$($LFS path2fid $DIR/$tfile)
9988
9989         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9990         then
9991                 check_ost=true
9992                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9993                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9994         else
9995                 echo "OSS do not support bulk pages dump upon error"
9996         fi
9997
9998         osc_file_prefix=$($LCTL get_param -n debug_path)
9999         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10000
10001         trap cleanup_77c EXIT
10002
10003         set_checksums 1
10004         # enable bulk pages dump upon error on Client
10005         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10006         # enable bulk pages dump upon error on OSS
10007         $check_ost &&
10008                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10009
10010         # flush Client cache to allow next read to reach OSS
10011         cancel_lru_locks osc
10012
10013         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10014         $LCTL set_param fail_loc=0x80000408
10015         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10016         $LCTL set_param fail_loc=0
10017
10018         rm -f $DIR/$tfile
10019
10020         # check cksum dump on Client
10021         osc_file=$(ls ${osc_file_prefix}*)
10022         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10023         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10024         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10025         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10026         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10027                      cksum)
10028         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10029         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10030                 error "dump content does not match on Client"
10031
10032         $check_ost || skip "No need to check cksum dump on OSS"
10033
10034         # check cksum dump on OSS
10035         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10036         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10037         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10038         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10039         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10040                 error "dump content does not match on OSS"
10041
10042         cleanup_77c
10043 }
10044 run_test 77c "checksum error on client read with debug"
10045
10046 test_77d() { # bug 10889
10047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10048         $GSS && skip_env "could not run with gss"
10049
10050         stack_trap "rm -f $DIR/$tfile"
10051         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10052         $LCTL set_param fail_loc=0x80000409
10053         set_checksums 1
10054         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10055                 error "direct write: rc=$?"
10056         $LCTL set_param fail_loc=0
10057         set_checksums 0
10058
10059         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10060         $LCTL set_param fail_loc=0x80000408
10061         set_checksums 1
10062         cancel_lru_locks osc
10063         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10064                 error "direct read: rc=$?"
10065         $LCTL set_param fail_loc=0
10066         set_checksums 0
10067 }
10068 run_test 77d "checksum error on OST direct write, read"
10069
10070 test_77f() { # bug 10889
10071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10072         $GSS && skip_env "could not run with gss"
10073
10074         set_checksums 1
10075         stack_trap "rm -f $DIR/$tfile"
10076         for algo in $CKSUM_TYPES; do
10077                 cancel_lru_locks osc
10078                 set_checksum_type $algo
10079                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10080                 $LCTL set_param fail_loc=0x409
10081                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10082                         error "direct write succeeded"
10083                 $LCTL set_param fail_loc=0
10084         done
10085         set_checksum_type $ORIG_CSUM_TYPE
10086         set_checksums 0
10087 }
10088 run_test 77f "repeat checksum error on write (expect error)"
10089
10090 test_77g() { # bug 10889
10091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10092         $GSS && skip_env "could not run with gss"
10093         remote_ost_nodsh && skip "remote OST with nodsh"
10094
10095         [ ! -f $F77_TMP ] && setup_f77
10096
10097         local file=$DIR/$tfile
10098         stack_trap "rm -f $file" EXIT
10099
10100         $LFS setstripe -c 1 -i 0 $file
10101         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10102         do_facet ost1 lctl set_param fail_loc=0x8000021a
10103         set_checksums 1
10104         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10105                 error "write error: rc=$?"
10106         do_facet ost1 lctl set_param fail_loc=0
10107         set_checksums 0
10108
10109         cancel_lru_locks osc
10110         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10111         do_facet ost1 lctl set_param fail_loc=0x8000021b
10112         set_checksums 1
10113         cmp $F77_TMP $file || error "file compare failed"
10114         do_facet ost1 lctl set_param fail_loc=0
10115         set_checksums 0
10116 }
10117 run_test 77g "checksum error on OST write, read"
10118
10119 test_77k() { # LU-10906
10120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10121         $GSS && skip_env "could not run with gss"
10122
10123         local cksum_param="osc.$FSNAME*.checksums"
10124         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10125         local checksum
10126         local i
10127
10128         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10129         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10130         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10131
10132         for i in 0 1; do
10133                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10134                         error "failed to set checksum=$i on MGS"
10135                 wait_update $HOSTNAME "$get_checksum" $i
10136                 #remount
10137                 echo "remount client, checksum should be $i"
10138                 remount_client $MOUNT || error "failed to remount client"
10139                 checksum=$(eval $get_checksum)
10140                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10141         done
10142         # remove persistent param to avoid races with checksum mountopt below
10143         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10144                 error "failed to delete checksum on MGS"
10145
10146         for opt in "checksum" "nochecksum"; do
10147                 #remount with mount option
10148                 echo "remount client with option $opt, checksum should be $i"
10149                 umount_client $MOUNT || error "failed to umount client"
10150                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10151                         error "failed to mount client with option '$opt'"
10152                 checksum=$(eval $get_checksum)
10153                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10154                 i=$((i - 1))
10155         done
10156
10157         remount_client $MOUNT || error "failed to remount client"
10158 }
10159 run_test 77k "enable/disable checksum correctly"
10160
10161 test_77l() {
10162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10163         $GSS && skip_env "could not run with gss"
10164
10165         set_checksums 1
10166         stack_trap "set_checksums $ORIG_CSUM" EXIT
10167         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10168
10169         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10170
10171         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10172         for algo in $CKSUM_TYPES; do
10173                 set_checksum_type $algo || error "fail to set checksum type $algo"
10174                 osc_algo=$(get_osc_checksum_type OST0000)
10175                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10176
10177                 # no locks, no reqs to let the connection idle
10178                 cancel_lru_locks osc
10179                 lru_resize_disable osc
10180                 wait_osc_import_state client ost1 IDLE
10181
10182                 # ensure ost1 is connected
10183                 stat $DIR/$tfile >/dev/null || error "can't stat"
10184                 wait_osc_import_state client ost1 FULL
10185
10186                 osc_algo=$(get_osc_checksum_type OST0000)
10187                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10188         done
10189         return 0
10190 }
10191 run_test 77l "preferred checksum type is remembered after reconnected"
10192
10193 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10194 rm -f $F77_TMP
10195 unset F77_TMP
10196
10197 test_77m() {
10198         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10199                 skip "Need at least version 2.14.52"
10200         local param=checksum_speed
10201
10202         $LCTL get_param $param || error "reading $param failed"
10203
10204         csum_speeds=$($LCTL get_param -n $param)
10205
10206         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10207                 error "known checksum types are missing"
10208 }
10209 run_test 77m "Verify checksum_speed is correctly read"
10210
10211 check_filefrag_77n() {
10212         local nr_ext=0
10213         local starts=()
10214         local ends=()
10215
10216         while read extidx a b start end rest; do
10217                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10218                         nr_ext=$(( $nr_ext + 1 ))
10219                         starts+=( ${start%..} )
10220                         ends+=( ${end%:} )
10221                 fi
10222         done < <( filefrag -sv $1 )
10223
10224         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10225         return 1
10226 }
10227
10228 test_77n() {
10229         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10230
10231         touch $DIR/$tfile
10232         $TRUNCATE $DIR/$tfile 0
10233         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10234         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10235         check_filefrag_77n $DIR/$tfile ||
10236                 skip "$tfile blocks not contiguous around hole"
10237
10238         set_checksums 1
10239         stack_trap "set_checksums $ORIG_CSUM" EXIT
10240         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10241         stack_trap "rm -f $DIR/$tfile"
10242
10243         for algo in $CKSUM_TYPES; do
10244                 if [[ "$algo" =~ ^t10 ]]; then
10245                         set_checksum_type $algo ||
10246                                 error "fail to set checksum type $algo"
10247                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10248                                 error "fail to read $tfile with $algo"
10249                 fi
10250         done
10251         rm -f $DIR/$tfile
10252         return 0
10253 }
10254 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10255
10256 test_77o() {
10257         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10258                 skip "Need MDS version at least 2.14.55"
10259         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10260                 skip "Need OST version at least 2.14.55"
10261         local ofd=obdfilter
10262         local mdt=mdt
10263
10264         # print OST checksum_type
10265         echo "$ofd.$FSNAME-*.checksum_type:"
10266         do_nodes $(comma_list $(osts_nodes)) \
10267                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10268
10269         # print MDT checksum_type
10270         echo "$mdt.$FSNAME-*.checksum_type:"
10271         do_nodes $(comma_list $(mdts_nodes)) \
10272                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10273
10274         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10275                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10276
10277         (( $o_count == $OSTCOUNT )) ||
10278                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10279
10280         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10281                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10282
10283         (( $m_count == $MDSCOUNT )) ||
10284                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10285 }
10286 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10287
10288 cleanup_test_78() {
10289         trap 0
10290         rm -f $DIR/$tfile
10291 }
10292
10293 test_78() { # bug 10901
10294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10295         remote_ost || skip_env "local OST"
10296
10297         NSEQ=5
10298         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10299         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10300         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10301         echo "MemTotal: $MEMTOTAL"
10302
10303         # reserve 256MB of memory for the kernel and other running processes,
10304         # and then take 1/2 of the remaining memory for the read/write buffers.
10305         if [ $MEMTOTAL -gt 512 ] ;then
10306                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10307         else
10308                 # for those poor memory-starved high-end clusters...
10309                 MEMTOTAL=$((MEMTOTAL / 2))
10310         fi
10311         echo "Mem to use for directio: $MEMTOTAL"
10312
10313         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10314         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10315         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10316         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10317                 head -n1)
10318         echo "Smallest OST: $SMALLESTOST"
10319         [[ $SMALLESTOST -lt 10240 ]] &&
10320                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10321
10322         trap cleanup_test_78 EXIT
10323
10324         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10325                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10326
10327         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10328         echo "File size: $F78SIZE"
10329         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10330         for i in $(seq 1 $NSEQ); do
10331                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10332                 echo directIO rdwr round $i of $NSEQ
10333                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10334         done
10335
10336         cleanup_test_78
10337 }
10338 run_test 78 "handle large O_DIRECT writes correctly ============"
10339
10340 test_79() { # bug 12743
10341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10342
10343         wait_delete_completed
10344
10345         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10346         BKFREE=$(calc_osc_kbytes kbytesfree)
10347         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10348
10349         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10350         DFTOTAL=`echo $STRING | cut -d, -f1`
10351         DFUSED=`echo $STRING  | cut -d, -f2`
10352         DFAVAIL=`echo $STRING | cut -d, -f3`
10353         DFFREE=$(($DFTOTAL - $DFUSED))
10354
10355         ALLOWANCE=$((64 * $OSTCOUNT))
10356
10357         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10358            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10359                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10360         fi
10361         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10362            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10363                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10364         fi
10365         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10366            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10367                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10368         fi
10369 }
10370 run_test 79 "df report consistency check ======================="
10371
10372 test_80() { # bug 10718
10373         remote_ost_nodsh && skip "remote OST with nodsh"
10374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10375
10376         # relax strong synchronous semantics for slow backends like ZFS
10377         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10378                 local soc="obdfilter.*.sync_lock_cancel"
10379                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10380
10381                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10382                 if [ -z "$save" ]; then
10383                         soc="obdfilter.*.sync_on_lock_cancel"
10384                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10385                 fi
10386
10387                 if [ "$save" != "never" ]; then
10388                         local hosts=$(comma_list $(osts_nodes))
10389
10390                         do_nodes $hosts $LCTL set_param $soc=never
10391                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10392                 fi
10393         fi
10394
10395         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10396         sync; sleep 1; sync
10397         local before=$(date +%s)
10398         cancel_lru_locks osc
10399         local after=$(date +%s)
10400         local diff=$((after - before))
10401         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10402
10403         rm -f $DIR/$tfile
10404 }
10405 run_test 80 "Page eviction is equally fast at high offsets too"
10406
10407 test_81a() { # LU-456
10408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10409         remote_ost_nodsh && skip "remote OST with nodsh"
10410
10411         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10412         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10413         do_facet ost1 lctl set_param fail_loc=0x80000228
10414
10415         # write should trigger a retry and success
10416         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10417         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10418         RC=$?
10419         if [ $RC -ne 0 ] ; then
10420                 error "write should success, but failed for $RC"
10421         fi
10422 }
10423 run_test 81a "OST should retry write when get -ENOSPC ==============="
10424
10425 test_81b() { # LU-456
10426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10427         remote_ost_nodsh && skip "remote OST with nodsh"
10428
10429         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10430         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10431         do_facet ost1 lctl set_param fail_loc=0x228
10432
10433         # write should retry several times and return -ENOSPC finally
10434         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10435         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10436         RC=$?
10437         ENOSPC=28
10438         if [ $RC -ne $ENOSPC ] ; then
10439                 error "dd should fail for -ENOSPC, but succeed."
10440         fi
10441 }
10442 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10443
10444 test_99() {
10445         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10446
10447         test_mkdir $DIR/$tdir.cvsroot
10448         chown $RUNAS_ID $DIR/$tdir.cvsroot
10449
10450         cd $TMP
10451         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10452
10453         cd /etc/init.d
10454         # some versions of cvs import exit(1) when asked to import links or
10455         # files they can't read.  ignore those files.
10456         local toignore=$(find . -type l -printf '-I %f\n' -o \
10457                          ! -perm /4 -printf '-I %f\n')
10458         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10459                 $tdir.reposname vtag rtag
10460
10461         cd $DIR
10462         test_mkdir $DIR/$tdir.reposname
10463         chown $RUNAS_ID $DIR/$tdir.reposname
10464         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10465
10466         cd $DIR/$tdir.reposname
10467         $RUNAS touch foo99
10468         $RUNAS cvs add -m 'addmsg' foo99
10469         $RUNAS cvs update
10470         $RUNAS cvs commit -m 'nomsg' foo99
10471         rm -fr $DIR/$tdir.cvsroot
10472 }
10473 run_test 99 "cvs strange file/directory operations"
10474
10475 test_100() {
10476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10477         [[ "$NETTYPE" =~ tcp ]] ||
10478                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10479         remote_ost_nodsh && skip "remote OST with nodsh"
10480         remote_mds_nodsh && skip "remote MDS with nodsh"
10481         remote_servers ||
10482                 skip "useless for local single node setup"
10483
10484         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10485                 [ "$PROT" != "tcp" ] && continue
10486                 RPORT=$(echo $REMOTE | cut -d: -f2)
10487                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10488
10489                 rc=0
10490                 LPORT=`echo $LOCAL | cut -d: -f2`
10491                 if [ $LPORT -ge 1024 ]; then
10492                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10493                         netstat -tna
10494                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10495                 fi
10496         done
10497         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10498 }
10499 run_test 100 "check local port using privileged port ==========="
10500
10501 function get_named_value()
10502 {
10503     local tag=$1
10504
10505     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10506 }
10507
10508 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10509                    awk '/^max_cached_mb/ { print $2 }')
10510
10511 cleanup_101a() {
10512         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10513         trap 0
10514 }
10515
10516 test_101a() {
10517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10518
10519         local s
10520         local discard
10521         local nreads=10000
10522         local cache_limit=32
10523
10524         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10525         trap cleanup_101a EXIT
10526         $LCTL set_param -n llite.*.read_ahead_stats=0
10527         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10528
10529         #
10530         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10531         #
10532         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10533         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10534
10535         discard=0
10536         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10537                    get_named_value 'read.but.discarded'); do
10538                         discard=$(($discard + $s))
10539         done
10540         cleanup_101a
10541
10542         $LCTL get_param osc.*-osc*.rpc_stats
10543         $LCTL get_param llite.*.read_ahead_stats
10544
10545         # Discard is generally zero, but sometimes a few random reads line up
10546         # and trigger larger readahead, which is wasted & leads to discards.
10547         if [[ $(($discard)) -gt $nreads ]]; then
10548                 error "too many ($discard) discarded pages"
10549         fi
10550         rm -f $DIR/$tfile || true
10551 }
10552 run_test 101a "check read-ahead for random reads"
10553
10554 setup_test101bc() {
10555         test_mkdir $DIR/$tdir
10556         local ssize=$1
10557         local FILE_LENGTH=$2
10558         STRIPE_OFFSET=0
10559
10560         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10561
10562         local list=$(comma_list $(osts_nodes))
10563         set_osd_param $list '' read_cache_enable 0
10564         set_osd_param $list '' writethrough_cache_enable 0
10565
10566         trap cleanup_test101bc EXIT
10567         # prepare the read-ahead file
10568         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10569
10570         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10571                                 count=$FILE_SIZE_MB 2> /dev/null
10572
10573 }
10574
10575 cleanup_test101bc() {
10576         trap 0
10577         rm -rf $DIR/$tdir
10578         rm -f $DIR/$tfile
10579
10580         local list=$(comma_list $(osts_nodes))
10581         set_osd_param $list '' read_cache_enable 1
10582         set_osd_param $list '' writethrough_cache_enable 1
10583 }
10584
10585 calc_total() {
10586         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10587 }
10588
10589 ra_check_101() {
10590         local read_size=$1
10591         local stripe_size=$2
10592         local stride_length=$((stripe_size / read_size))
10593         local stride_width=$((stride_length * OSTCOUNT))
10594         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10595                                 (stride_width - stride_length) ))
10596         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10597                   get_named_value 'read.but.discarded' | calc_total)
10598
10599         if [[ $discard -gt $discard_limit ]]; then
10600                 $LCTL get_param llite.*.read_ahead_stats
10601                 error "($discard) discarded pages with size (${read_size})"
10602         else
10603                 echo "Read-ahead success for size ${read_size}"
10604         fi
10605 }
10606
10607 test_101b() {
10608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10609         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10610
10611         local STRIPE_SIZE=1048576
10612         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10613
10614         if [ $SLOW == "yes" ]; then
10615                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10616         else
10617                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10618         fi
10619
10620         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10621
10622         # prepare the read-ahead file
10623         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10624         cancel_lru_locks osc
10625         for BIDX in 2 4 8 16 32 64 128 256
10626         do
10627                 local BSIZE=$((BIDX*4096))
10628                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10629                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10630                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10631                 $LCTL set_param -n llite.*.read_ahead_stats=0
10632                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10633                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10634                 cancel_lru_locks osc
10635                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10636         done
10637         cleanup_test101bc
10638         true
10639 }
10640 run_test 101b "check stride-io mode read-ahead ================="
10641
10642 test_101c() {
10643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10644
10645         local STRIPE_SIZE=1048576
10646         local FILE_LENGTH=$((STRIPE_SIZE*100))
10647         local nreads=10000
10648         local rsize=65536
10649         local osc_rpc_stats
10650
10651         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10652
10653         cancel_lru_locks osc
10654         $LCTL set_param osc.*.rpc_stats=0
10655         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10656         $LCTL get_param osc.*.rpc_stats
10657         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10658                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10659                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10660                 local size
10661
10662                 if [ $lines -le 20 ]; then
10663                         echo "continue debug"
10664                         continue
10665                 fi
10666                 for size in 1 2 4 8; do
10667                         local rpc=$(echo "$stats" |
10668                                     awk '($1 == "'$size':") {print $2; exit; }')
10669                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10670                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10671                 done
10672                 echo "$osc_rpc_stats check passed!"
10673         done
10674         cleanup_test101bc
10675         true
10676 }
10677 run_test 101c "check stripe_size aligned read-ahead"
10678
10679 test_101d() {
10680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10681
10682         local file=$DIR/$tfile
10683         local sz_MB=${FILESIZE_101d:-80}
10684         local ra_MB=${READAHEAD_MB:-40}
10685
10686         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10687         [ $free_MB -lt $sz_MB ] &&
10688                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10689
10690         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10691         $LFS setstripe -c -1 $file || error "setstripe failed"
10692
10693         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10694         echo Cancel LRU locks on lustre client to flush the client cache
10695         cancel_lru_locks osc
10696
10697         echo Disable read-ahead
10698         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10699         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10700         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10701         $LCTL get_param -n llite.*.max_read_ahead_mb
10702
10703         echo "Reading the test file $file with read-ahead disabled"
10704         local sz_KB=$((sz_MB * 1024 / 4))
10705         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10706         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10707         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10708                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10709
10710         echo "Cancel LRU locks on lustre client to flush the client cache"
10711         cancel_lru_locks osc
10712         echo Enable read-ahead with ${ra_MB}MB
10713         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10714
10715         echo "Reading the test file $file with read-ahead enabled"
10716         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10717                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10718
10719         echo "read-ahead disabled time read $raOFF"
10720         echo "read-ahead enabled time read $raON"
10721
10722         rm -f $file
10723         wait_delete_completed
10724
10725         # use awk for this check instead of bash because it handles decimals
10726         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10727                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10728 }
10729 run_test 101d "file read with and without read-ahead enabled"
10730
10731 test_101e() {
10732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10733
10734         local file=$DIR/$tfile
10735         local size_KB=500  #KB
10736         local count=100
10737         local bsize=1024
10738
10739         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10740         local need_KB=$((count * size_KB))
10741         [[ $free_KB -le $need_KB ]] &&
10742                 skip_env "Need free space $need_KB, have $free_KB"
10743
10744         echo "Creating $count ${size_KB}K test files"
10745         for ((i = 0; i < $count; i++)); do
10746                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10747         done
10748
10749         echo "Cancel LRU locks on lustre client to flush the client cache"
10750         cancel_lru_locks $OSC
10751
10752         echo "Reset readahead stats"
10753         $LCTL set_param -n llite.*.read_ahead_stats=0
10754
10755         for ((i = 0; i < $count; i++)); do
10756                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10757         done
10758
10759         $LCTL get_param llite.*.max_cached_mb
10760         $LCTL get_param llite.*.read_ahead_stats
10761         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10762                      get_named_value 'misses' | calc_total)
10763
10764         for ((i = 0; i < $count; i++)); do
10765                 rm -rf $file.$i 2>/dev/null
10766         done
10767
10768         #10000 means 20% reads are missing in readahead
10769         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10770 }
10771 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10772
10773 test_101f() {
10774         which iozone || skip_env "no iozone installed"
10775
10776         local old_debug=$($LCTL get_param debug)
10777         old_debug=${old_debug#*=}
10778         $LCTL set_param debug="reada mmap"
10779
10780         # create a test file
10781         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10782
10783         echo Cancel LRU locks on lustre client to flush the client cache
10784         cancel_lru_locks osc
10785
10786         echo Reset readahead stats
10787         $LCTL set_param -n llite.*.read_ahead_stats=0
10788
10789         echo mmap read the file with small block size
10790         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10791                 > /dev/null 2>&1
10792
10793         echo checking missing pages
10794         $LCTL get_param llite.*.read_ahead_stats
10795         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10796                         get_named_value 'misses' | calc_total)
10797
10798         $LCTL set_param debug="$old_debug"
10799         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10800         rm -f $DIR/$tfile
10801 }
10802 run_test 101f "check mmap read performance"
10803
10804 test_101g_brw_size_test() {
10805         local mb=$1
10806         local pages=$((mb * 1048576 / PAGE_SIZE))
10807         local file=$DIR/$tfile
10808
10809         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10810                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10811         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10812                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10813                         return 2
10814         done
10815
10816         stack_trap "rm -f $file" EXIT
10817         $LCTL set_param -n osc.*.rpc_stats=0
10818
10819         # 10 RPCs should be enough for the test
10820         local count=10
10821         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10822                 { error "dd write ${mb} MB blocks failed"; return 3; }
10823         cancel_lru_locks osc
10824         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10825                 { error "dd write ${mb} MB blocks failed"; return 4; }
10826
10827         # calculate number of full-sized read and write RPCs
10828         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10829                 sed -n '/pages per rpc/,/^$/p' |
10830                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10831                 END { print reads,writes }'))
10832         # allow one extra full-sized read RPC for async readahead
10833         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10834                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10835         [[ ${rpcs[1]} == $count ]] ||
10836                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10837 }
10838
10839 test_101g() {
10840         remote_ost_nodsh && skip "remote OST with nodsh"
10841
10842         local rpcs
10843         local osts=$(get_facets OST)
10844         local list=$(comma_list $(osts_nodes))
10845         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10846         local brw_size="obdfilter.*.brw_size"
10847
10848         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10849
10850         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10851
10852         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10853                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10854                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10855            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10856                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10857                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10858
10859                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10860                         suffix="M"
10861
10862                 if [[ $orig_mb -lt 16 ]]; then
10863                         save_lustre_params $osts "$brw_size" > $p
10864                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10865                                 error "set 16MB RPC size failed"
10866
10867                         echo "remount client to enable new RPC size"
10868                         remount_client $MOUNT || error "remount_client failed"
10869                 fi
10870
10871                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10872                 # should be able to set brw_size=12, but no rpc_stats for that
10873                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10874         fi
10875
10876         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10877
10878         if [[ $orig_mb -lt 16 ]]; then
10879                 restore_lustre_params < $p
10880                 remount_client $MOUNT || error "remount_client restore failed"
10881         fi
10882
10883         rm -f $p $DIR/$tfile
10884 }
10885 run_test 101g "Big bulk(4/16 MiB) readahead"
10886
10887 test_101h() {
10888         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10889
10890         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10891                 error "dd 70M file failed"
10892         echo Cancel LRU locks on lustre client to flush the client cache
10893         cancel_lru_locks osc
10894
10895         echo "Reset readahead stats"
10896         $LCTL set_param -n llite.*.read_ahead_stats 0
10897
10898         echo "Read 10M of data but cross 64M bundary"
10899         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10900         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10901                      get_named_value 'misses' | calc_total)
10902         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10903         rm -f $p $DIR/$tfile
10904 }
10905 run_test 101h "Readahead should cover current read window"
10906
10907 test_101i() {
10908         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10909                 error "dd 10M file failed"
10910
10911         local max_per_file_mb=$($LCTL get_param -n \
10912                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10913         cancel_lru_locks osc
10914         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10915         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10916                 error "set max_read_ahead_per_file_mb to 1 failed"
10917
10918         echo "Reset readahead stats"
10919         $LCTL set_param llite.*.read_ahead_stats=0
10920
10921         dd if=$DIR/$tfile of=/dev/null bs=2M
10922
10923         $LCTL get_param llite.*.read_ahead_stats
10924         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10925                      awk '/misses/ { print $2 }')
10926         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10927         rm -f $DIR/$tfile
10928 }
10929 run_test 101i "allow current readahead to exceed reservation"
10930
10931 test_101j() {
10932         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10933                 error "setstripe $DIR/$tfile failed"
10934         local file_size=$((1048576 * 16))
10935         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10936         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10937
10938         echo Disable read-ahead
10939         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10940
10941         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10942         for blk in $PAGE_SIZE 1048576 $file_size; do
10943                 cancel_lru_locks osc
10944                 echo "Reset readahead stats"
10945                 $LCTL set_param -n llite.*.read_ahead_stats=0
10946                 local count=$(($file_size / $blk))
10947                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10948                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10949                              get_named_value 'failed.to.fast.read' | calc_total)
10950                 $LCTL get_param -n llite.*.read_ahead_stats
10951                 [ $miss -eq $count ] || error "expected $count got $miss"
10952         done
10953
10954         rm -f $p $DIR/$tfile
10955 }
10956 run_test 101j "A complete read block should be submitted when no RA"
10957
10958 setup_test102() {
10959         test_mkdir $DIR/$tdir
10960         chown $RUNAS_ID $DIR/$tdir
10961         STRIPE_SIZE=65536
10962         STRIPE_OFFSET=1
10963         STRIPE_COUNT=$OSTCOUNT
10964         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10965
10966         trap cleanup_test102 EXIT
10967         cd $DIR
10968         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10969         cd $DIR/$tdir
10970         for num in 1 2 3 4; do
10971                 for count in $(seq 1 $STRIPE_COUNT); do
10972                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10973                                 local size=`expr $STRIPE_SIZE \* $num`
10974                                 local file=file"$num-$idx-$count"
10975                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10976                         done
10977                 done
10978         done
10979
10980         cd $DIR
10981         $1 tar cf $TMP/f102.tar $tdir --xattrs
10982 }
10983
10984 cleanup_test102() {
10985         trap 0
10986         rm -f $TMP/f102.tar
10987         rm -rf $DIR/d0.sanity/d102
10988 }
10989
10990 test_102a() {
10991         [ "$UID" != 0 ] && skip "must run as root"
10992         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10993                 skip_env "must have user_xattr"
10994
10995         [ -z "$(which setfattr 2>/dev/null)" ] &&
10996                 skip_env "could not find setfattr"
10997
10998         local testfile=$DIR/$tfile
10999
11000         touch $testfile
11001         echo "set/get xattr..."
11002         setfattr -n trusted.name1 -v value1 $testfile ||
11003                 error "setfattr -n trusted.name1=value1 $testfile failed"
11004         getfattr -n trusted.name1 $testfile 2> /dev/null |
11005           grep "trusted.name1=.value1" ||
11006                 error "$testfile missing trusted.name1=value1"
11007
11008         setfattr -n user.author1 -v author1 $testfile ||
11009                 error "setfattr -n user.author1=author1 $testfile failed"
11010         getfattr -n user.author1 $testfile 2> /dev/null |
11011           grep "user.author1=.author1" ||
11012                 error "$testfile missing trusted.author1=author1"
11013
11014         echo "listxattr..."
11015         setfattr -n trusted.name2 -v value2 $testfile ||
11016                 error "$testfile unable to set trusted.name2"
11017         setfattr -n trusted.name3 -v value3 $testfile ||
11018                 error "$testfile unable to set trusted.name3"
11019         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11020             grep "trusted.name" | wc -l) -eq 3 ] ||
11021                 error "$testfile missing 3 trusted.name xattrs"
11022
11023         setfattr -n user.author2 -v author2 $testfile ||
11024                 error "$testfile unable to set user.author2"
11025         setfattr -n user.author3 -v author3 $testfile ||
11026                 error "$testfile unable to set user.author3"
11027         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11028             grep "user.author" | wc -l) -eq 3 ] ||
11029                 error "$testfile missing 3 user.author xattrs"
11030
11031         echo "remove xattr..."
11032         setfattr -x trusted.name1 $testfile ||
11033                 error "$testfile error deleting trusted.name1"
11034         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11035                 error "$testfile did not delete trusted.name1 xattr"
11036
11037         setfattr -x user.author1 $testfile ||
11038                 error "$testfile error deleting user.author1"
11039         echo "set lustre special xattr ..."
11040         $LFS setstripe -c1 $testfile
11041         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11042                 awk -F "=" '/trusted.lov/ { print $2 }' )
11043         setfattr -n "trusted.lov" -v $lovea $testfile ||
11044                 error "$testfile doesn't ignore setting trusted.lov again"
11045         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11046                 error "$testfile allow setting invalid trusted.lov"
11047         rm -f $testfile
11048 }
11049 run_test 102a "user xattr test =================================="
11050
11051 check_102b_layout() {
11052         local layout="$*"
11053         local testfile=$DIR/$tfile
11054
11055         echo "test layout '$layout'"
11056         $LFS setstripe $layout $testfile || error "setstripe failed"
11057         $LFS getstripe -y $testfile
11058
11059         echo "get/set/list trusted.lov xattr ..." # b=10930
11060         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11061         [[ "$value" =~ "trusted.lov" ]] ||
11062                 error "can't get trusted.lov from $testfile"
11063         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11064                 error "getstripe failed"
11065
11066         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11067
11068         value=$(cut -d= -f2 <<<$value)
11069         # LU-13168: truncated xattr should fail if short lov_user_md header
11070         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11071                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11072         for len in $lens; do
11073                 echo "setfattr $len $testfile.2"
11074                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11075                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11076         done
11077         local stripe_size=$($LFS getstripe -S $testfile.2)
11078         local stripe_count=$($LFS getstripe -c $testfile.2)
11079         [[ $stripe_size -eq 65536 ]] ||
11080                 error "stripe size $stripe_size != 65536"
11081         [[ $stripe_count -eq $stripe_count_orig ]] ||
11082                 error "stripe count $stripe_count != $stripe_count_orig"
11083         rm $testfile $testfile.2
11084 }
11085
11086 test_102b() {
11087         [ -z "$(which setfattr 2>/dev/null)" ] &&
11088                 skip_env "could not find setfattr"
11089         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11090
11091         # check plain layout
11092         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11093
11094         # and also check composite layout
11095         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11096
11097 }
11098 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11099
11100 test_102c() {
11101         [ -z "$(which setfattr 2>/dev/null)" ] &&
11102                 skip_env "could not find setfattr"
11103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11104
11105         # b10930: get/set/list lustre.lov xattr
11106         echo "get/set/list lustre.lov xattr ..."
11107         test_mkdir $DIR/$tdir
11108         chown $RUNAS_ID $DIR/$tdir
11109         local testfile=$DIR/$tdir/$tfile
11110         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11111                 error "setstripe failed"
11112         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11113                 error "getstripe failed"
11114         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11115         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11116
11117         local testfile2=${testfile}2
11118         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11119                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11120
11121         $RUNAS $MCREATE $testfile2
11122         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11123         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11124         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11125         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11126         [ $stripe_count -eq $STRIPECOUNT ] ||
11127                 error "stripe count $stripe_count != $STRIPECOUNT"
11128 }
11129 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11130
11131 compare_stripe_info1() {
11132         local stripe_index_all_zero=true
11133
11134         for num in 1 2 3 4; do
11135                 for count in $(seq 1 $STRIPE_COUNT); do
11136                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11137                                 local size=$((STRIPE_SIZE * num))
11138                                 local file=file"$num-$offset-$count"
11139                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11140                                 [[ $stripe_size -ne $size ]] &&
11141                                     error "$file: size $stripe_size != $size"
11142                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11143                                 # allow fewer stripes to be created, ORI-601
11144                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11145                                     error "$file: count $stripe_count != $count"
11146                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11147                                 [[ $stripe_index -ne 0 ]] &&
11148                                         stripe_index_all_zero=false
11149                         done
11150                 done
11151         done
11152         $stripe_index_all_zero &&
11153                 error "all files are being extracted starting from OST index 0"
11154         return 0
11155 }
11156
11157 have_xattrs_include() {
11158         tar --help | grep -q xattrs-include &&
11159                 echo --xattrs-include="lustre.*"
11160 }
11161
11162 test_102d() {
11163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11164         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11165
11166         XINC=$(have_xattrs_include)
11167         setup_test102
11168         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11169         cd $DIR/$tdir/$tdir
11170         compare_stripe_info1
11171 }
11172 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11173
11174 test_102f() {
11175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11176         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11177
11178         XINC=$(have_xattrs_include)
11179         setup_test102
11180         test_mkdir $DIR/$tdir.restore
11181         cd $DIR
11182         tar cf - --xattrs $tdir | tar xf - \
11183                 -C $DIR/$tdir.restore --xattrs $XINC
11184         cd $DIR/$tdir.restore/$tdir
11185         compare_stripe_info1
11186 }
11187 run_test 102f "tar copy files, not keep osts"
11188
11189 grow_xattr() {
11190         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11191                 skip "must have user_xattr"
11192         [ -z "$(which setfattr 2>/dev/null)" ] &&
11193                 skip_env "could not find setfattr"
11194         [ -z "$(which getfattr 2>/dev/null)" ] &&
11195                 skip_env "could not find getfattr"
11196
11197         local xsize=${1:-1024}  # in bytes
11198         local file=$DIR/$tfile
11199         local value="$(generate_string $xsize)"
11200         local xbig=trusted.big
11201         local toobig=$2
11202
11203         touch $file
11204         log "save $xbig on $file"
11205         if [ -z "$toobig" ]
11206         then
11207                 setfattr -n $xbig -v $value $file ||
11208                         error "saving $xbig on $file failed"
11209         else
11210                 setfattr -n $xbig -v $value $file &&
11211                         error "saving $xbig on $file succeeded"
11212                 return 0
11213         fi
11214
11215         local orig=$(get_xattr_value $xbig $file)
11216         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11217
11218         local xsml=trusted.sml
11219         log "save $xsml on $file"
11220         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11221
11222         local new=$(get_xattr_value $xbig $file)
11223         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11224
11225         log "grow $xsml on $file"
11226         setfattr -n $xsml -v "$value" $file ||
11227                 error "growing $xsml on $file failed"
11228
11229         new=$(get_xattr_value $xbig $file)
11230         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11231         log "$xbig still valid after growing $xsml"
11232
11233         rm -f $file
11234 }
11235
11236 test_102h() { # bug 15777
11237         grow_xattr 1024
11238 }
11239 run_test 102h "grow xattr from inside inode to external block"
11240
11241 test_102ha() {
11242         large_xattr_enabled || skip_env "ea_inode feature disabled"
11243
11244         echo "setting xattr of max xattr size: $(max_xattr_size)"
11245         grow_xattr $(max_xattr_size)
11246
11247         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11248         echo "This should fail:"
11249         grow_xattr $(($(max_xattr_size) + 10)) 1
11250 }
11251 run_test 102ha "grow xattr from inside inode to external inode"
11252
11253 test_102i() { # bug 17038
11254         [ -z "$(which getfattr 2>/dev/null)" ] &&
11255                 skip "could not find getfattr"
11256
11257         touch $DIR/$tfile
11258         ln -s $DIR/$tfile $DIR/${tfile}link
11259         getfattr -n trusted.lov $DIR/$tfile ||
11260                 error "lgetxattr on $DIR/$tfile failed"
11261         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11262                 grep -i "no such attr" ||
11263                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11264         rm -f $DIR/$tfile $DIR/${tfile}link
11265 }
11266 run_test 102i "lgetxattr test on symbolic link ============"
11267
11268 test_102j() {
11269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11270         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11271
11272         XINC=$(have_xattrs_include)
11273         setup_test102 "$RUNAS"
11274         chown $RUNAS_ID $DIR/$tdir
11275         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11276         cd $DIR/$tdir/$tdir
11277         compare_stripe_info1 "$RUNAS"
11278 }
11279 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11280
11281 test_102k() {
11282         [ -z "$(which setfattr 2>/dev/null)" ] &&
11283                 skip "could not find setfattr"
11284
11285         touch $DIR/$tfile
11286         # b22187 just check that does not crash for regular file.
11287         setfattr -n trusted.lov $DIR/$tfile
11288         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11289         local test_kdir=$DIR/$tdir
11290         test_mkdir $test_kdir
11291         local default_size=$($LFS getstripe -S $test_kdir)
11292         local default_count=$($LFS getstripe -c $test_kdir)
11293         local default_offset=$($LFS getstripe -i $test_kdir)
11294         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11295                 error 'dir setstripe failed'
11296         setfattr -n trusted.lov $test_kdir
11297         local stripe_size=$($LFS getstripe -S $test_kdir)
11298         local stripe_count=$($LFS getstripe -c $test_kdir)
11299         local stripe_offset=$($LFS getstripe -i $test_kdir)
11300         [ $stripe_size -eq $default_size ] ||
11301                 error "stripe size $stripe_size != $default_size"
11302         [ $stripe_count -eq $default_count ] ||
11303                 error "stripe count $stripe_count != $default_count"
11304         [ $stripe_offset -eq $default_offset ] ||
11305                 error "stripe offset $stripe_offset != $default_offset"
11306         rm -rf $DIR/$tfile $test_kdir
11307 }
11308 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11309
11310 test_102l() {
11311         [ -z "$(which getfattr 2>/dev/null)" ] &&
11312                 skip "could not find getfattr"
11313
11314         # LU-532 trusted. xattr is invisible to non-root
11315         local testfile=$DIR/$tfile
11316
11317         touch $testfile
11318
11319         echo "listxattr as user..."
11320         chown $RUNAS_ID $testfile
11321         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11322             grep -q "trusted" &&
11323                 error "$testfile trusted xattrs are user visible"
11324
11325         return 0;
11326 }
11327 run_test 102l "listxattr size test =================================="
11328
11329 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11330         local path=$DIR/$tfile
11331         touch $path
11332
11333         listxattr_size_check $path || error "listattr_size_check $path failed"
11334 }
11335 run_test 102m "Ensure listxattr fails on small bufffer ========"
11336
11337 cleanup_test102
11338
11339 getxattr() { # getxattr path name
11340         # Return the base64 encoding of the value of xattr name on path.
11341         local path=$1
11342         local name=$2
11343
11344         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11345         # file: $path
11346         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11347         #
11348         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11349
11350         getfattr --absolute-names --encoding=base64 --name=$name $path |
11351                 awk -F= -v name=$name '$1 == name {
11352                         print substr($0, index($0, "=") + 1);
11353         }'
11354 }
11355
11356 test_102n() { # LU-4101 mdt: protect internal xattrs
11357         [ -z "$(which setfattr 2>/dev/null)" ] &&
11358                 skip "could not find setfattr"
11359         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11360         then
11361                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11362         fi
11363
11364         local file0=$DIR/$tfile.0
11365         local file1=$DIR/$tfile.1
11366         local xattr0=$TMP/$tfile.0
11367         local xattr1=$TMP/$tfile.1
11368         local namelist="lov lma lmv link fid version som hsm"
11369         local name
11370         local value
11371
11372         rm -rf $file0 $file1 $xattr0 $xattr1
11373         touch $file0 $file1
11374
11375         # Get 'before' xattrs of $file1.
11376         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11377
11378         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11379                 namelist+=" lfsck_namespace"
11380         for name in $namelist; do
11381                 # Try to copy xattr from $file0 to $file1.
11382                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11383
11384                 setfattr --name=trusted.$name --value="$value" $file1 ||
11385                         error "setxattr 'trusted.$name' failed"
11386
11387                 # Try to set a garbage xattr.
11388                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11389
11390                 if [[ x$name == "xlov" ]]; then
11391                         setfattr --name=trusted.lov --value="$value" $file1 &&
11392                         error "setxattr invalid 'trusted.lov' success"
11393                 else
11394                         setfattr --name=trusted.$name --value="$value" $file1 ||
11395                                 error "setxattr invalid 'trusted.$name' failed"
11396                 fi
11397
11398                 # Try to remove the xattr from $file1. We don't care if this
11399                 # appears to succeed or fail, we just don't want there to be
11400                 # any changes or crashes.
11401                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11402         done
11403
11404         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11405         then
11406                 name="lfsck_ns"
11407                 # Try to copy xattr from $file0 to $file1.
11408                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11409
11410                 setfattr --name=trusted.$name --value="$value" $file1 ||
11411                         error "setxattr 'trusted.$name' failed"
11412
11413                 # Try to set a garbage xattr.
11414                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11415
11416                 setfattr --name=trusted.$name --value="$value" $file1 ||
11417                         error "setxattr 'trusted.$name' failed"
11418
11419                 # Try to remove the xattr from $file1. We don't care if this
11420                 # appears to succeed or fail, we just don't want there to be
11421                 # any changes or crashes.
11422                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11423         fi
11424
11425         # Get 'after' xattrs of file1.
11426         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11427
11428         if ! diff $xattr0 $xattr1; then
11429                 error "before and after xattrs of '$file1' differ"
11430         fi
11431
11432         rm -rf $file0 $file1 $xattr0 $xattr1
11433
11434         return 0
11435 }
11436 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11437
11438 test_102p() { # LU-4703 setxattr did not check ownership
11439         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11440                 skip "MDS needs to be at least 2.5.56"
11441
11442         local testfile=$DIR/$tfile
11443
11444         touch $testfile
11445
11446         echo "setfacl as user..."
11447         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11448         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11449
11450         echo "setfattr as user..."
11451         setfacl -m "u:$RUNAS_ID:---" $testfile
11452         $RUNAS setfattr -x system.posix_acl_access $testfile
11453         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11454 }
11455 run_test 102p "check setxattr(2) correctly fails without permission"
11456
11457 test_102q() {
11458         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11459                 skip "MDS needs to be at least 2.6.92"
11460
11461         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11462 }
11463 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11464
11465 test_102r() {
11466         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11467                 skip "MDS needs to be at least 2.6.93"
11468
11469         touch $DIR/$tfile || error "touch"
11470         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11471         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11472         rm $DIR/$tfile || error "rm"
11473
11474         #normal directory
11475         mkdir -p $DIR/$tdir || error "mkdir"
11476         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11477         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11478         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11479                 error "$testfile error deleting user.author1"
11480         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11481                 grep "user.$(basename $tdir)" &&
11482                 error "$tdir did not delete user.$(basename $tdir)"
11483         rmdir $DIR/$tdir || error "rmdir"
11484
11485         #striped directory
11486         test_mkdir $DIR/$tdir
11487         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11488         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11489         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11490                 error "$testfile error deleting user.author1"
11491         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11492                 grep "user.$(basename $tdir)" &&
11493                 error "$tdir did not delete user.$(basename $tdir)"
11494         rmdir $DIR/$tdir || error "rm striped dir"
11495 }
11496 run_test 102r "set EAs with empty values"
11497
11498 test_102s() {
11499         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11500                 skip "MDS needs to be at least 2.11.52"
11501
11502         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11503
11504         save_lustre_params client "llite.*.xattr_cache" > $save
11505
11506         for cache in 0 1; do
11507                 lctl set_param llite.*.xattr_cache=$cache
11508
11509                 rm -f $DIR/$tfile
11510                 touch $DIR/$tfile || error "touch"
11511                 for prefix in lustre security system trusted user; do
11512                         # Note getxattr() may fail with 'Operation not
11513                         # supported' or 'No such attribute' depending
11514                         # on prefix and cache.
11515                         getfattr -n $prefix.n102s $DIR/$tfile &&
11516                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11517                 done
11518         done
11519
11520         restore_lustre_params < $save
11521 }
11522 run_test 102s "getting nonexistent xattrs should fail"
11523
11524 test_102t() {
11525         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11526                 skip "MDS needs to be at least 2.11.52"
11527
11528         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11529
11530         save_lustre_params client "llite.*.xattr_cache" > $save
11531
11532         for cache in 0 1; do
11533                 lctl set_param llite.*.xattr_cache=$cache
11534
11535                 for buf_size in 0 256; do
11536                         rm -f $DIR/$tfile
11537                         touch $DIR/$tfile || error "touch"
11538                         setfattr -n user.multiop $DIR/$tfile
11539                         $MULTIOP $DIR/$tfile oa$buf_size ||
11540                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11541                 done
11542         done
11543
11544         restore_lustre_params < $save
11545 }
11546 run_test 102t "zero length xattr values handled correctly"
11547
11548 run_acl_subtest()
11549 {
11550     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11551     return $?
11552 }
11553
11554 test_103a() {
11555         [ "$UID" != 0 ] && skip "must run as root"
11556         $GSS && skip_env "could not run under gss"
11557         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11558                 skip_env "must have acl enabled"
11559         [ -z "$(which setfacl 2>/dev/null)" ] &&
11560                 skip_env "could not find setfacl"
11561         remote_mds_nodsh && skip "remote MDS with nodsh"
11562
11563         gpasswd -a daemon bin                           # LU-5641
11564         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11565
11566         declare -a identity_old
11567
11568         for num in $(seq $MDSCOUNT); do
11569                 switch_identity $num true || identity_old[$num]=$?
11570         done
11571
11572         SAVE_UMASK=$(umask)
11573         umask 0022
11574         mkdir -p $DIR/$tdir
11575         cd $DIR/$tdir
11576
11577         echo "performing cp ..."
11578         run_acl_subtest cp || error "run_acl_subtest cp failed"
11579         echo "performing getfacl-noacl..."
11580         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11581         echo "performing misc..."
11582         run_acl_subtest misc || error  "misc test failed"
11583         echo "performing permissions..."
11584         run_acl_subtest permissions || error "permissions failed"
11585         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11586         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11587                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11588                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11589         then
11590                 echo "performing permissions xattr..."
11591                 run_acl_subtest permissions_xattr ||
11592                         error "permissions_xattr failed"
11593         fi
11594         echo "performing setfacl..."
11595         run_acl_subtest setfacl || error  "setfacl test failed"
11596
11597         # inheritance test got from HP
11598         echo "performing inheritance..."
11599         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11600         chmod +x make-tree || error "chmod +x failed"
11601         run_acl_subtest inheritance || error "inheritance test failed"
11602         rm -f make-tree
11603
11604         echo "LU-974 ignore umask when acl is enabled..."
11605         run_acl_subtest 974 || error "LU-974 umask test failed"
11606         if [ $MDSCOUNT -ge 2 ]; then
11607                 run_acl_subtest 974_remote ||
11608                         error "LU-974 umask test failed under remote dir"
11609         fi
11610
11611         echo "LU-2561 newly created file is same size as directory..."
11612         if [ "$mds1_FSTYPE" != "zfs" ]; then
11613                 run_acl_subtest 2561 || error "LU-2561 test failed"
11614         else
11615                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11616         fi
11617
11618         run_acl_subtest 4924 || error "LU-4924 test failed"
11619
11620         cd $SAVE_PWD
11621         umask $SAVE_UMASK
11622
11623         for num in $(seq $MDSCOUNT); do
11624                 if [ "${identity_old[$num]}" = 1 ]; then
11625                         switch_identity $num false || identity_old[$num]=$?
11626                 fi
11627         done
11628 }
11629 run_test 103a "acl test"
11630
11631 test_103b() {
11632         declare -a pids
11633         local U
11634
11635         for U in {0..511}; do
11636                 {
11637                 local O=$(printf "%04o" $U)
11638
11639                 umask $(printf "%04o" $((511 ^ $O)))
11640                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11641                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11642
11643                 (( $S == ($O & 0666) )) ||
11644                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11645
11646                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11647                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11648                 (( $S == ($O & 0666) )) ||
11649                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11650
11651                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11652                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11653                 (( $S == ($O & 0666) )) ||
11654                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11655                 rm -f $DIR/$tfile.[smp]$0
11656                 } &
11657                 local pid=$!
11658
11659                 # limit the concurrently running threads to 64. LU-11878
11660                 local idx=$((U % 64))
11661                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11662                 pids[idx]=$pid
11663         done
11664         wait
11665 }
11666 run_test 103b "umask lfs setstripe"
11667
11668 test_103c() {
11669         mkdir -p $DIR/$tdir
11670         cp -rp $DIR/$tdir $DIR/$tdir.bak
11671
11672         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11673                 error "$DIR/$tdir shouldn't contain default ACL"
11674         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11675                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11676         true
11677 }
11678 run_test 103c "'cp -rp' won't set empty acl"
11679
11680 test_103e() {
11681         local numacl
11682         local fileacl
11683         local saved_debug=$($LCTL get_param -n debug)
11684
11685         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11686                 skip "MDS needs to be at least 2.14.52"
11687
11688         large_xattr_enabled || skip_env "ea_inode feature disabled"
11689
11690         mkdir -p $DIR/$tdir
11691         # add big LOV EA to cause reply buffer overflow earlier
11692         $LFS setstripe -C 1000 $DIR/$tdir
11693         lctl set_param mdc.*-mdc*.stats=clear
11694
11695         $LCTL set_param debug=0
11696         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11697         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11698
11699         # add a large number of default ACLs (expect 8000+ for 2.13+)
11700         for U in {2..7000}; do
11701                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11702                         error "Able to add just $U default ACLs"
11703         done
11704         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11705         echo "$numacl default ACLs created"
11706
11707         stat $DIR/$tdir || error "Cannot stat directory"
11708         # check file creation
11709         touch $DIR/$tdir/$tfile ||
11710                 error "failed to create $tfile with $numacl default ACLs"
11711         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11712         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11713         echo "$fileacl ACLs were inherited"
11714         (( $fileacl == $numacl )) ||
11715                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11716         # check that new ACLs creation adds new ACLs to inherited ACLs
11717         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11718                 error "Cannot set new ACL"
11719         numacl=$((numacl + 1))
11720         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11721         (( $fileacl == $numacl )) ||
11722                 error "failed to add new ACL: $fileacl != $numacl as expected"
11723         # adds more ACLs to a file to reach their maximum at 8000+
11724         numacl=0
11725         for U in {20000..25000}; do
11726                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11727                 numacl=$((numacl + 1))
11728         done
11729         echo "Added $numacl more ACLs to the file"
11730         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11731         echo "Total $fileacl ACLs in file"
11732         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11733         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11734         rmdir $DIR/$tdir || error "Cannot remove directory"
11735 }
11736 run_test 103e "inheritance of big amount of default ACLs"
11737
11738 test_103f() {
11739         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11740                 skip "MDS needs to be at least 2.14.51"
11741
11742         large_xattr_enabled || skip_env "ea_inode feature disabled"
11743
11744         # enable changelog to consume more internal MDD buffers
11745         changelog_register
11746
11747         mkdir -p $DIR/$tdir
11748         # add big LOV EA
11749         $LFS setstripe -C 1000 $DIR/$tdir
11750         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11751         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11752         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11753         rmdir $DIR/$tdir || error "Cannot remove directory"
11754 }
11755 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11756
11757 test_104a() {
11758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11759
11760         touch $DIR/$tfile
11761         lfs df || error "lfs df failed"
11762         lfs df -ih || error "lfs df -ih failed"
11763         lfs df -h $DIR || error "lfs df -h $DIR failed"
11764         lfs df -i $DIR || error "lfs df -i $DIR failed"
11765         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11766         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11767
11768         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11769         lctl --device %$OSC deactivate
11770         lfs df || error "lfs df with deactivated OSC failed"
11771         lctl --device %$OSC activate
11772         # wait the osc back to normal
11773         wait_osc_import_ready client ost
11774
11775         lfs df || error "lfs df with reactivated OSC failed"
11776         rm -f $DIR/$tfile
11777 }
11778 run_test 104a "lfs df [-ih] [path] test ========================="
11779
11780 test_104b() {
11781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11782         [ $RUNAS_ID -eq $UID ] &&
11783                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11784
11785         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11786                         grep "Permission denied" | wc -l)))
11787         if [ $denied_cnt -ne 0 ]; then
11788                 error "lfs check servers test failed"
11789         fi
11790 }
11791 run_test 104b "$RUNAS lfs check servers test ===================="
11792
11793 #
11794 # Verify $1 is within range of $2.
11795 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11796 # $1 is <= 2% of $2. Else Fail.
11797 #
11798 value_in_range() {
11799         # Strip all units (M, G, T)
11800         actual=$(echo $1 | tr -d A-Z)
11801         expect=$(echo $2 | tr -d A-Z)
11802
11803         expect_lo=$(($expect * 98 / 100)) # 2% below
11804         expect_hi=$(($expect * 102 / 100)) # 2% above
11805
11806         # permit 2% drift above and below
11807         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11808 }
11809
11810 test_104c() {
11811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11812         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11813
11814         local ost_param="osd-zfs.$FSNAME-OST0000."
11815         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11816         local ofacets=$(get_facets OST)
11817         local mfacets=$(get_facets MDS)
11818         local saved_ost_blocks=
11819         local saved_mdt_blocks=
11820
11821         echo "Before recordsize change"
11822         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11823         df=($(df -h | grep "$MOUNT"$))
11824
11825         # For checking.
11826         echo "lfs output : ${lfs_df[*]}"
11827         echo "df  output : ${df[*]}"
11828
11829         for facet in ${ofacets//,/ }; do
11830                 if [ -z $saved_ost_blocks ]; then
11831                         saved_ost_blocks=$(do_facet $facet \
11832                                 lctl get_param -n $ost_param.blocksize)
11833                         echo "OST Blocksize: $saved_ost_blocks"
11834                 fi
11835                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11836                 do_facet $facet zfs set recordsize=32768 $ost
11837         done
11838
11839         # BS too small. Sufficient for functional testing.
11840         for facet in ${mfacets//,/ }; do
11841                 if [ -z $saved_mdt_blocks ]; then
11842                         saved_mdt_blocks=$(do_facet $facet \
11843                                 lctl get_param -n $mdt_param.blocksize)
11844                         echo "MDT Blocksize: $saved_mdt_blocks"
11845                 fi
11846                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11847                 do_facet $facet zfs set recordsize=32768 $mdt
11848         done
11849
11850         # Give new values chance to reflect change
11851         sleep 2
11852
11853         echo "After recordsize change"
11854         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11855         df_after=($(df -h | grep "$MOUNT"$))
11856
11857         # For checking.
11858         echo "lfs output : ${lfs_df_after[*]}"
11859         echo "df  output : ${df_after[*]}"
11860
11861         # Verify lfs df
11862         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11863                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11864         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11865                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11866         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11867                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11868
11869         # Verify df
11870         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11871                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11872         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11873                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11874         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11875                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11876
11877         # Restore MDT recordize back to original
11878         for facet in ${mfacets//,/ }; do
11879                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11880                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11881         done
11882
11883         # Restore OST recordize back to original
11884         for facet in ${ofacets//,/ }; do
11885                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11886                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11887         done
11888
11889         return 0
11890 }
11891 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11892
11893 test_105a() {
11894         # doesn't work on 2.4 kernels
11895         touch $DIR/$tfile
11896         if $(flock_is_enabled); then
11897                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11898         else
11899                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11900         fi
11901         rm -f $DIR/$tfile
11902 }
11903 run_test 105a "flock when mounted without -o flock test ========"
11904
11905 test_105b() {
11906         touch $DIR/$tfile
11907         if $(flock_is_enabled); then
11908                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11909         else
11910                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11911         fi
11912         rm -f $DIR/$tfile
11913 }
11914 run_test 105b "fcntl when mounted without -o flock test ========"
11915
11916 test_105c() {
11917         touch $DIR/$tfile
11918         if $(flock_is_enabled); then
11919                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11920         else
11921                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11922         fi
11923         rm -f $DIR/$tfile
11924 }
11925 run_test 105c "lockf when mounted without -o flock test"
11926
11927 test_105d() { # bug 15924
11928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11929
11930         test_mkdir $DIR/$tdir
11931         flock_is_enabled || skip_env "mount w/o flock enabled"
11932         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11933         $LCTL set_param fail_loc=0x80000315
11934         flocks_test 2 $DIR/$tdir
11935 }
11936 run_test 105d "flock race (should not freeze) ========"
11937
11938 test_105e() { # bug 22660 && 22040
11939         flock_is_enabled || skip_env "mount w/o flock enabled"
11940
11941         touch $DIR/$tfile
11942         flocks_test 3 $DIR/$tfile
11943 }
11944 run_test 105e "Two conflicting flocks from same process"
11945
11946 test_106() { #bug 10921
11947         test_mkdir $DIR/$tdir
11948         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11949         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11950 }
11951 run_test 106 "attempt exec of dir followed by chown of that dir"
11952
11953 test_107() {
11954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11955
11956         CDIR=`pwd`
11957         local file=core
11958
11959         cd $DIR
11960         rm -f $file
11961
11962         local save_pattern=$(sysctl -n kernel.core_pattern)
11963         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11964         sysctl -w kernel.core_pattern=$file
11965         sysctl -w kernel.core_uses_pid=0
11966
11967         ulimit -c unlimited
11968         sleep 60 &
11969         SLEEPPID=$!
11970
11971         sleep 1
11972
11973         kill -s 11 $SLEEPPID
11974         wait $SLEEPPID
11975         if [ -e $file ]; then
11976                 size=`stat -c%s $file`
11977                 [ $size -eq 0 ] && error "Fail to create core file $file"
11978         else
11979                 error "Fail to create core file $file"
11980         fi
11981         rm -f $file
11982         sysctl -w kernel.core_pattern=$save_pattern
11983         sysctl -w kernel.core_uses_pid=$save_uses_pid
11984         cd $CDIR
11985 }
11986 run_test 107 "Coredump on SIG"
11987
11988 test_110() {
11989         test_mkdir $DIR/$tdir
11990         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11991         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11992                 error "mkdir with 256 char should fail, but did not"
11993         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11994                 error "create with 255 char failed"
11995         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11996                 error "create with 256 char should fail, but did not"
11997
11998         ls -l $DIR/$tdir
11999         rm -rf $DIR/$tdir
12000 }
12001 run_test 110 "filename length checking"
12002
12003 #
12004 # Purpose: To verify dynamic thread (OSS) creation.
12005 #
12006 test_115() {
12007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12008         remote_ost_nodsh && skip "remote OST with nodsh"
12009
12010         # Lustre does not stop service threads once they are started.
12011         # Reset number of running threads to default.
12012         stopall
12013         setupall
12014
12015         local OSTIO_pre
12016         local save_params="$TMP/sanity-$TESTNAME.parameters"
12017
12018         # Get ll_ost_io count before I/O
12019         OSTIO_pre=$(do_facet ost1 \
12020                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
12021         # Exit if lustre is not running (ll_ost_io not running).
12022         [ -z "$OSTIO_pre" ] && error "no OSS threads"
12023
12024         echo "Starting with $OSTIO_pre threads"
12025         local thread_max=$((OSTIO_pre * 2))
12026         local rpc_in_flight=$((thread_max * 2))
12027         # this is limited to OSC_MAX_RIF_MAX (256)
12028         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
12029         thread_max=$((rpc_in_flight / 2))
12030         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
12031                 return
12032
12033         # Number of I/O Process proposed to be started.
12034         local nfiles
12035         local facets=$(get_facets OST)
12036
12037         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
12038         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
12039
12040         # Set in_flight to $rpc_in_flight
12041         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
12042                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
12043         nfiles=${rpc_in_flight}
12044         # Set ost thread_max to $thread_max
12045         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
12046
12047         # 5 Minutes should be sufficient for max number of OSS
12048         # threads(thread_max) to be created.
12049         local timeout=300
12050
12051         # Start I/O.
12052         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
12053         test_mkdir $DIR/$tdir
12054         for i in $(seq $nfiles); do
12055                 local file=$DIR/$tdir/${tfile}-$i
12056                 $LFS setstripe -c -1 -i 0 $file
12057                 ($WTL $file $timeout)&
12058         done
12059
12060         # I/O Started - Wait for thread_started to reach thread_max or report
12061         # error if thread_started is more than thread_max.
12062         echo "Waiting for thread_started to reach thread_max"
12063         local thread_started=0
12064         local end_time=$((SECONDS + timeout))
12065
12066         while [ $SECONDS -le $end_time ] ; do
12067                 echo -n "."
12068                 # Get ost i/o thread_started count.
12069                 thread_started=$(do_facet ost1 \
12070                         "$LCTL get_param \
12071                         ost.OSS.ost_io.threads_started | cut -d= -f2")
12072                 # Break out if thread_started is equal/greater than thread_max
12073                 if [[ $thread_started -ge $thread_max ]]; then
12074                         echo ll_ost_io thread_started $thread_started, \
12075                                 equal/greater than thread_max $thread_max
12076                         break
12077                 fi
12078                 sleep 1
12079         done
12080
12081         # Cleanup - We have the numbers, Kill i/o jobs if running.
12082         jobcount=($(jobs -p))
12083         for i in $(seq 0 $((${#jobcount[@]}-1)))
12084         do
12085                 kill -9 ${jobcount[$i]}
12086                 if [ $? -ne 0 ] ; then
12087                         echo Warning: \
12088                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12089                 fi
12090         done
12091
12092         # Cleanup files left by WTL binary.
12093         for i in $(seq $nfiles); do
12094                 local file=$DIR/$tdir/${tfile}-$i
12095                 rm -rf $file
12096                 if [ $? -ne 0 ] ; then
12097                         echo "Warning: Failed to delete file $file"
12098                 fi
12099         done
12100
12101         restore_lustre_params <$save_params
12102         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12103
12104         # Error out if no new thread has started or Thread started is greater
12105         # than thread max.
12106         if [[ $thread_started -le $OSTIO_pre ||
12107                         $thread_started -gt $thread_max ]]; then
12108                 error "ll_ost_io: thread_started $thread_started" \
12109                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12110                       "No new thread started or thread started greater " \
12111                       "than thread_max."
12112         fi
12113 }
12114 run_test 115 "verify dynamic thread creation===================="
12115
12116 test_116a() { # was previously test_116()
12117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12118         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12119         remote_mds_nodsh && skip "remote MDS with nodsh"
12120
12121         echo -n "Free space priority "
12122         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12123                 head -n1
12124         declare -a AVAIL
12125         free_min_max
12126
12127         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12128         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12129         stack_trap simple_cleanup_common
12130
12131         # Check if we need to generate uneven OSTs
12132         test_mkdir -p $DIR/$tdir/OST${MINI}
12133         local FILL=$((MINV / 4))
12134         local DIFF=$((MAXV - MINV))
12135         local DIFF2=$((DIFF * 100 / MINV))
12136
12137         local threshold=$(do_facet $SINGLEMDS \
12138                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12139         threshold=${threshold%%%}
12140         echo -n "Check for uneven OSTs: "
12141         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12142
12143         if [[ $DIFF2 -gt $threshold ]]; then
12144                 echo "ok"
12145                 echo "Don't need to fill OST$MINI"
12146         else
12147                 # generate uneven OSTs. Write 2% over the QOS threshold value
12148                 echo "no"
12149                 DIFF=$((threshold - DIFF2 + 2))
12150                 DIFF2=$((MINV * DIFF / 100))
12151                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12152                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12153                         error "setstripe failed"
12154                 DIFF=$((DIFF2 / 2048))
12155                 i=0
12156                 while [ $i -lt $DIFF ]; do
12157                         i=$((i + 1))
12158                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12159                                 bs=2M count=1 2>/dev/null
12160                         echo -n .
12161                 done
12162                 echo .
12163                 sync
12164                 sleep_maxage
12165                 free_min_max
12166         fi
12167
12168         DIFF=$((MAXV - MINV))
12169         DIFF2=$((DIFF * 100 / MINV))
12170         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12171         if [ $DIFF2 -gt $threshold ]; then
12172                 echo "ok"
12173         else
12174                 skip "QOS imbalance criteria not met"
12175         fi
12176
12177         MINI1=$MINI
12178         MINV1=$MINV
12179         MAXI1=$MAXI
12180         MAXV1=$MAXV
12181
12182         # now fill using QOS
12183         $LFS setstripe -c 1 $DIR/$tdir
12184         FILL=$((FILL / 200))
12185         if [ $FILL -gt 600 ]; then
12186                 FILL=600
12187         fi
12188         echo "writing $FILL files to QOS-assigned OSTs"
12189         i=0
12190         while [ $i -lt $FILL ]; do
12191                 i=$((i + 1))
12192                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12193                         count=1 2>/dev/null
12194                 echo -n .
12195         done
12196         echo "wrote $i 200k files"
12197         sync
12198         sleep_maxage
12199
12200         echo "Note: free space may not be updated, so measurements might be off"
12201         free_min_max
12202         DIFF2=$((MAXV - MINV))
12203         echo "free space delta: orig $DIFF final $DIFF2"
12204         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12205         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12206         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12207         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12208         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12209         if [[ $DIFF -gt 0 ]]; then
12210                 FILL=$((DIFF2 * 100 / DIFF - 100))
12211                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12212         fi
12213
12214         # Figure out which files were written where
12215         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12216                awk '/'$MINI1': / {print $2; exit}')
12217         echo $UUID
12218         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12219         echo "$MINC files created on smaller OST $MINI1"
12220         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12221                awk '/'$MAXI1': / {print $2; exit}')
12222         echo $UUID
12223         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12224         echo "$MAXC files created on larger OST $MAXI1"
12225         if [[ $MINC -gt 0 ]]; then
12226                 FILL=$((MAXC * 100 / MINC - 100))
12227                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12228         fi
12229         [[ $MAXC -gt $MINC ]] ||
12230                 error_ignore LU-9 "stripe QOS didn't balance free space"
12231 }
12232 run_test 116a "stripe QOS: free space balance ==================="
12233
12234 test_116b() { # LU-2093
12235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12236         remote_mds_nodsh && skip "remote MDS with nodsh"
12237
12238 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12239         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12240                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12241         [ -z "$old_rr" ] && skip "no QOS"
12242         do_facet $SINGLEMDS lctl set_param \
12243                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12244         mkdir -p $DIR/$tdir
12245         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12246         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12247         do_facet $SINGLEMDS lctl set_param fail_loc=0
12248         rm -rf $DIR/$tdir
12249         do_facet $SINGLEMDS lctl set_param \
12250                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12251 }
12252 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12253
12254 test_117() # bug 10891
12255 {
12256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12257
12258         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12259         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12260         lctl set_param fail_loc=0x21e
12261         > $DIR/$tfile || error "truncate failed"
12262         lctl set_param fail_loc=0
12263         echo "Truncate succeeded."
12264         rm -f $DIR/$tfile
12265 }
12266 run_test 117 "verify osd extend =========="
12267
12268 NO_SLOW_RESENDCOUNT=4
12269 export OLD_RESENDCOUNT=""
12270 set_resend_count () {
12271         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12272         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12273         lctl set_param -n $PROC_RESENDCOUNT $1
12274         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12275 }
12276
12277 # for reduce test_118* time (b=14842)
12278 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12279
12280 # Reset async IO behavior after error case
12281 reset_async() {
12282         FILE=$DIR/reset_async
12283
12284         # Ensure all OSCs are cleared
12285         $LFS setstripe -c -1 $FILE
12286         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12287         sync
12288         rm $FILE
12289 }
12290
12291 test_118a() #bug 11710
12292 {
12293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12294
12295         reset_async
12296
12297         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12298         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12299         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12300
12301         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12302                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12303                 return 1;
12304         fi
12305         rm -f $DIR/$tfile
12306 }
12307 run_test 118a "verify O_SYNC works =========="
12308
12309 test_118b()
12310 {
12311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12312         remote_ost_nodsh && skip "remote OST with nodsh"
12313
12314         reset_async
12315
12316         #define OBD_FAIL_SRV_ENOENT 0x217
12317         set_nodes_failloc "$(osts_nodes)" 0x217
12318         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12319         RC=$?
12320         set_nodes_failloc "$(osts_nodes)" 0
12321         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12322         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12323                     grep -c writeback)
12324
12325         if [[ $RC -eq 0 ]]; then
12326                 error "Must return error due to dropped pages, rc=$RC"
12327                 return 1;
12328         fi
12329
12330         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12331                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12332                 return 1;
12333         fi
12334
12335         echo "Dirty pages not leaked on ENOENT"
12336
12337         # Due to the above error the OSC will issue all RPCs syncronously
12338         # until a subsequent RPC completes successfully without error.
12339         $MULTIOP $DIR/$tfile Ow4096yc
12340         rm -f $DIR/$tfile
12341
12342         return 0
12343 }
12344 run_test 118b "Reclaim dirty pages on fatal error =========="
12345
12346 test_118c()
12347 {
12348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12349
12350         # for 118c, restore the original resend count, LU-1940
12351         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12352                                 set_resend_count $OLD_RESENDCOUNT
12353         remote_ost_nodsh && skip "remote OST with nodsh"
12354
12355         reset_async
12356
12357         #define OBD_FAIL_OST_EROFS               0x216
12358         set_nodes_failloc "$(osts_nodes)" 0x216
12359
12360         # multiop should block due to fsync until pages are written
12361         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12362         MULTIPID=$!
12363         sleep 1
12364
12365         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12366                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12367         fi
12368
12369         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12370                     grep -c writeback)
12371         if [[ $WRITEBACK -eq 0 ]]; then
12372                 error "No page in writeback, writeback=$WRITEBACK"
12373         fi
12374
12375         set_nodes_failloc "$(osts_nodes)" 0
12376         wait $MULTIPID
12377         RC=$?
12378         if [[ $RC -ne 0 ]]; then
12379                 error "Multiop fsync failed, rc=$RC"
12380         fi
12381
12382         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12383         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12384                     grep -c writeback)
12385         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12386                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12387         fi
12388
12389         rm -f $DIR/$tfile
12390         echo "Dirty pages flushed via fsync on EROFS"
12391         return 0
12392 }
12393 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12394
12395 # continue to use small resend count to reduce test_118* time (b=14842)
12396 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12397
12398 test_118d()
12399 {
12400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12401         remote_ost_nodsh && skip "remote OST with nodsh"
12402
12403         reset_async
12404
12405         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12406         set_nodes_failloc "$(osts_nodes)" 0x214
12407         # multiop should block due to fsync until pages are written
12408         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12409         MULTIPID=$!
12410         sleep 1
12411
12412         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12413                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12414         fi
12415
12416         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12417                     grep -c writeback)
12418         if [[ $WRITEBACK -eq 0 ]]; then
12419                 error "No page in writeback, writeback=$WRITEBACK"
12420         fi
12421
12422         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12423         set_nodes_failloc "$(osts_nodes)" 0
12424
12425         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12426         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12427                     grep -c writeback)
12428         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12429                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12430         fi
12431
12432         rm -f $DIR/$tfile
12433         echo "Dirty pages gaurenteed flushed via fsync"
12434         return 0
12435 }
12436 run_test 118d "Fsync validation inject a delay of the bulk =========="
12437
12438 test_118f() {
12439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12440
12441         reset_async
12442
12443         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12444         lctl set_param fail_loc=0x8000040a
12445
12446         # Should simulate EINVAL error which is fatal
12447         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12448         RC=$?
12449         if [[ $RC -eq 0 ]]; then
12450                 error "Must return error due to dropped pages, rc=$RC"
12451         fi
12452
12453         lctl set_param fail_loc=0x0
12454
12455         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12456         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12457         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12458                     grep -c writeback)
12459         if [[ $LOCKED -ne 0 ]]; then
12460                 error "Locked pages remain in cache, locked=$LOCKED"
12461         fi
12462
12463         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12464                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12465         fi
12466
12467         rm -f $DIR/$tfile
12468         echo "No pages locked after fsync"
12469
12470         reset_async
12471         return 0
12472 }
12473 run_test 118f "Simulate unrecoverable OSC side error =========="
12474
12475 test_118g() {
12476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12477
12478         reset_async
12479
12480         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12481         lctl set_param fail_loc=0x406
12482
12483         # simulate local -ENOMEM
12484         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12485         RC=$?
12486
12487         lctl set_param fail_loc=0
12488         if [[ $RC -eq 0 ]]; then
12489                 error "Must return error due to dropped pages, rc=$RC"
12490         fi
12491
12492         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12493         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12494         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12495                         grep -c writeback)
12496         if [[ $LOCKED -ne 0 ]]; then
12497                 error "Locked pages remain in cache, locked=$LOCKED"
12498         fi
12499
12500         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12501                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12502         fi
12503
12504         rm -f $DIR/$tfile
12505         echo "No pages locked after fsync"
12506
12507         reset_async
12508         return 0
12509 }
12510 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12511
12512 test_118h() {
12513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12514         remote_ost_nodsh && skip "remote OST with nodsh"
12515
12516         reset_async
12517
12518         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12519         set_nodes_failloc "$(osts_nodes)" 0x20e
12520         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12521         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12522         RC=$?
12523
12524         set_nodes_failloc "$(osts_nodes)" 0
12525         if [[ $RC -eq 0 ]]; then
12526                 error "Must return error due to dropped pages, rc=$RC"
12527         fi
12528
12529         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12530         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12531         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12532                     grep -c writeback)
12533         if [[ $LOCKED -ne 0 ]]; then
12534                 error "Locked pages remain in cache, locked=$LOCKED"
12535         fi
12536
12537         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12538                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12539         fi
12540
12541         rm -f $DIR/$tfile
12542         echo "No pages locked after fsync"
12543
12544         return 0
12545 }
12546 run_test 118h "Verify timeout in handling recoverables errors  =========="
12547
12548 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12549
12550 test_118i() {
12551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12552         remote_ost_nodsh && skip "remote OST with nodsh"
12553
12554         reset_async
12555
12556         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12557         set_nodes_failloc "$(osts_nodes)" 0x20e
12558
12559         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12560         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12561         PID=$!
12562         sleep 5
12563         set_nodes_failloc "$(osts_nodes)" 0
12564
12565         wait $PID
12566         RC=$?
12567         if [[ $RC -ne 0 ]]; then
12568                 error "got error, but should be not, rc=$RC"
12569         fi
12570
12571         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12572         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12573         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12574         if [[ $LOCKED -ne 0 ]]; then
12575                 error "Locked pages remain in cache, locked=$LOCKED"
12576         fi
12577
12578         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12579                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12580         fi
12581
12582         rm -f $DIR/$tfile
12583         echo "No pages locked after fsync"
12584
12585         return 0
12586 }
12587 run_test 118i "Fix error before timeout in recoverable error  =========="
12588
12589 [ "$SLOW" = "no" ] && set_resend_count 4
12590
12591 test_118j() {
12592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12593         remote_ost_nodsh && skip "remote OST with nodsh"
12594
12595         reset_async
12596
12597         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12598         set_nodes_failloc "$(osts_nodes)" 0x220
12599
12600         # return -EIO from OST
12601         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12602         RC=$?
12603         set_nodes_failloc "$(osts_nodes)" 0x0
12604         if [[ $RC -eq 0 ]]; then
12605                 error "Must return error due to dropped pages, rc=$RC"
12606         fi
12607
12608         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12609         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12610         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12611         if [[ $LOCKED -ne 0 ]]; then
12612                 error "Locked pages remain in cache, locked=$LOCKED"
12613         fi
12614
12615         # in recoverable error on OST we want resend and stay until it finished
12616         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12617                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12618         fi
12619
12620         rm -f $DIR/$tfile
12621         echo "No pages locked after fsync"
12622
12623         return 0
12624 }
12625 run_test 118j "Simulate unrecoverable OST side error =========="
12626
12627 test_118k()
12628 {
12629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12630         remote_ost_nodsh && skip "remote OSTs with nodsh"
12631
12632         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12633         set_nodes_failloc "$(osts_nodes)" 0x20e
12634         test_mkdir $DIR/$tdir
12635
12636         for ((i=0;i<10;i++)); do
12637                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12638                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12639                 SLEEPPID=$!
12640                 sleep 0.500s
12641                 kill $SLEEPPID
12642                 wait $SLEEPPID
12643         done
12644
12645         set_nodes_failloc "$(osts_nodes)" 0
12646         rm -rf $DIR/$tdir
12647 }
12648 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12649
12650 test_118l() # LU-646
12651 {
12652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12653
12654         test_mkdir $DIR/$tdir
12655         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12656         rm -rf $DIR/$tdir
12657 }
12658 run_test 118l "fsync dir"
12659
12660 test_118m() # LU-3066
12661 {
12662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12663
12664         test_mkdir $DIR/$tdir
12665         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12666         rm -rf $DIR/$tdir
12667 }
12668 run_test 118m "fdatasync dir ========="
12669
12670 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12671
12672 test_118n()
12673 {
12674         local begin
12675         local end
12676
12677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12678         remote_ost_nodsh && skip "remote OSTs with nodsh"
12679
12680         # Sleep to avoid a cached response.
12681         #define OBD_STATFS_CACHE_SECONDS 1
12682         sleep 2
12683
12684         # Inject a 10 second delay in the OST_STATFS handler.
12685         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12686         set_nodes_failloc "$(osts_nodes)" 0x242
12687
12688         begin=$SECONDS
12689         stat --file-system $MOUNT > /dev/null
12690         end=$SECONDS
12691
12692         set_nodes_failloc "$(osts_nodes)" 0
12693
12694         if ((end - begin > 20)); then
12695             error "statfs took $((end - begin)) seconds, expected 10"
12696         fi
12697 }
12698 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12699
12700 test_119a() # bug 11737
12701 {
12702         BSIZE=$((512 * 1024))
12703         directio write $DIR/$tfile 0 1 $BSIZE
12704         # We ask to read two blocks, which is more than a file size.
12705         # directio will indicate an error when requested and actual
12706         # sizes aren't equeal (a normal situation in this case) and
12707         # print actual read amount.
12708         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12709         if [ "$NOB" != "$BSIZE" ]; then
12710                 error "read $NOB bytes instead of $BSIZE"
12711         fi
12712         rm -f $DIR/$tfile
12713 }
12714 run_test 119a "Short directIO read must return actual read amount"
12715
12716 test_119b() # bug 11737
12717 {
12718         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12719
12720         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12721         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12722         sync
12723         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12724                 error "direct read failed"
12725         rm -f $DIR/$tfile
12726 }
12727 run_test 119b "Sparse directIO read must return actual read amount"
12728
12729 test_119c() # bug 13099
12730 {
12731         BSIZE=1048576
12732         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12733         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12734         rm -f $DIR/$tfile
12735 }
12736 run_test 119c "Testing for direct read hitting hole"
12737
12738 test_119d() # bug 15950
12739 {
12740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12741
12742         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12743         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12744         BSIZE=1048576
12745         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12746         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12747         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12748         lctl set_param fail_loc=0x40d
12749         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12750         pid_dio=$!
12751         sleep 1
12752         cat $DIR/$tfile > /dev/null &
12753         lctl set_param fail_loc=0
12754         pid_reads=$!
12755         wait $pid_dio
12756         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12757         sleep 2
12758         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12759         error "the read rpcs have not completed in 2s"
12760         rm -f $DIR/$tfile
12761         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12762 }
12763 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12764
12765 test_120a() {
12766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12767         remote_mds_nodsh && skip "remote MDS with nodsh"
12768         test_mkdir -i0 -c1 $DIR/$tdir
12769         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12770                 skip_env "no early lock cancel on server"
12771
12772         lru_resize_disable mdc
12773         lru_resize_disable osc
12774         cancel_lru_locks mdc
12775         # asynchronous object destroy at MDT could cause bl ast to client
12776         cancel_lru_locks osc
12777
12778         stat $DIR/$tdir > /dev/null
12779         can1=$(do_facet mds1 \
12780                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12781                awk '/ldlm_cancel/ {print $2}')
12782         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12783                awk '/ldlm_bl_callback/ {print $2}')
12784         test_mkdir -i0 -c1 $DIR/$tdir/d1
12785         can2=$(do_facet mds1 \
12786                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12787                awk '/ldlm_cancel/ {print $2}')
12788         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12789                awk '/ldlm_bl_callback/ {print $2}')
12790         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12791         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12792         lru_resize_enable mdc
12793         lru_resize_enable osc
12794 }
12795 run_test 120a "Early Lock Cancel: mkdir test"
12796
12797 test_120b() {
12798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12799         remote_mds_nodsh && skip "remote MDS with nodsh"
12800         test_mkdir $DIR/$tdir
12801         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12802                 skip_env "no early lock cancel on server"
12803
12804         lru_resize_disable mdc
12805         lru_resize_disable osc
12806         cancel_lru_locks mdc
12807         stat $DIR/$tdir > /dev/null
12808         can1=$(do_facet $SINGLEMDS \
12809                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12810                awk '/ldlm_cancel/ {print $2}')
12811         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12812                awk '/ldlm_bl_callback/ {print $2}')
12813         touch $DIR/$tdir/f1
12814         can2=$(do_facet $SINGLEMDS \
12815                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12816                awk '/ldlm_cancel/ {print $2}')
12817         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12818                awk '/ldlm_bl_callback/ {print $2}')
12819         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12820         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12821         lru_resize_enable mdc
12822         lru_resize_enable osc
12823 }
12824 run_test 120b "Early Lock Cancel: create test"
12825
12826 test_120c() {
12827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12828         remote_mds_nodsh && skip "remote MDS with nodsh"
12829         test_mkdir -i0 -c1 $DIR/$tdir
12830         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12831                 skip "no early lock cancel on server"
12832
12833         lru_resize_disable mdc
12834         lru_resize_disable osc
12835         test_mkdir -i0 -c1 $DIR/$tdir/d1
12836         test_mkdir -i0 -c1 $DIR/$tdir/d2
12837         touch $DIR/$tdir/d1/f1
12838         cancel_lru_locks mdc
12839         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12840         can1=$(do_facet mds1 \
12841                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12842                awk '/ldlm_cancel/ {print $2}')
12843         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12844                awk '/ldlm_bl_callback/ {print $2}')
12845         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12846         can2=$(do_facet mds1 \
12847                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12848                awk '/ldlm_cancel/ {print $2}')
12849         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12850                awk '/ldlm_bl_callback/ {print $2}')
12851         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12852         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12853         lru_resize_enable mdc
12854         lru_resize_enable osc
12855 }
12856 run_test 120c "Early Lock Cancel: link test"
12857
12858 test_120d() {
12859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12860         remote_mds_nodsh && skip "remote MDS with nodsh"
12861         test_mkdir -i0 -c1 $DIR/$tdir
12862         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12863                 skip_env "no early lock cancel on server"
12864
12865         lru_resize_disable mdc
12866         lru_resize_disable osc
12867         touch $DIR/$tdir
12868         cancel_lru_locks mdc
12869         stat $DIR/$tdir > /dev/null
12870         can1=$(do_facet mds1 \
12871                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12872                awk '/ldlm_cancel/ {print $2}')
12873         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12874                awk '/ldlm_bl_callback/ {print $2}')
12875         chmod a+x $DIR/$tdir
12876         can2=$(do_facet mds1 \
12877                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12878                awk '/ldlm_cancel/ {print $2}')
12879         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12880                awk '/ldlm_bl_callback/ {print $2}')
12881         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12882         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12883         lru_resize_enable mdc
12884         lru_resize_enable osc
12885 }
12886 run_test 120d "Early Lock Cancel: setattr test"
12887
12888 test_120e() {
12889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12890         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12891                 skip_env "no early lock cancel on server"
12892         remote_mds_nodsh && skip "remote MDS with nodsh"
12893
12894         local dlmtrace_set=false
12895
12896         test_mkdir -i0 -c1 $DIR/$tdir
12897         lru_resize_disable mdc
12898         lru_resize_disable osc
12899         ! $LCTL get_param debug | grep -q dlmtrace &&
12900                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12901         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12902         cancel_lru_locks mdc
12903         cancel_lru_locks osc
12904         dd if=$DIR/$tdir/f1 of=/dev/null
12905         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12906         # XXX client can not do early lock cancel of OST lock
12907         # during unlink (LU-4206), so cancel osc lock now.
12908         sleep 2
12909         cancel_lru_locks osc
12910         can1=$(do_facet mds1 \
12911                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12912                awk '/ldlm_cancel/ {print $2}')
12913         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12914                awk '/ldlm_bl_callback/ {print $2}')
12915         unlink $DIR/$tdir/f1
12916         sleep 5
12917         can2=$(do_facet mds1 \
12918                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12919                awk '/ldlm_cancel/ {print $2}')
12920         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12921                awk '/ldlm_bl_callback/ {print $2}')
12922         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12923                 $LCTL dk $TMP/cancel.debug.txt
12924         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12925                 $LCTL dk $TMP/blocking.debug.txt
12926         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12927         lru_resize_enable mdc
12928         lru_resize_enable osc
12929 }
12930 run_test 120e "Early Lock Cancel: unlink test"
12931
12932 test_120f() {
12933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12934         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12935                 skip_env "no early lock cancel on server"
12936         remote_mds_nodsh && skip "remote MDS with nodsh"
12937
12938         test_mkdir -i0 -c1 $DIR/$tdir
12939         lru_resize_disable mdc
12940         lru_resize_disable osc
12941         test_mkdir -i0 -c1 $DIR/$tdir/d1
12942         test_mkdir -i0 -c1 $DIR/$tdir/d2
12943         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12944         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12945         cancel_lru_locks mdc
12946         cancel_lru_locks osc
12947         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12948         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12949         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12950         # XXX client can not do early lock cancel of OST lock
12951         # during rename (LU-4206), so cancel osc lock now.
12952         sleep 2
12953         cancel_lru_locks osc
12954         can1=$(do_facet mds1 \
12955                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12956                awk '/ldlm_cancel/ {print $2}')
12957         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12958                awk '/ldlm_bl_callback/ {print $2}')
12959         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12960         sleep 5
12961         can2=$(do_facet mds1 \
12962                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12963                awk '/ldlm_cancel/ {print $2}')
12964         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12965                awk '/ldlm_bl_callback/ {print $2}')
12966         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12967         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12968         lru_resize_enable mdc
12969         lru_resize_enable osc
12970 }
12971 run_test 120f "Early Lock Cancel: rename test"
12972
12973 test_120g() {
12974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12975         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12976                 skip_env "no early lock cancel on server"
12977         remote_mds_nodsh && skip "remote MDS with nodsh"
12978
12979         lru_resize_disable mdc
12980         lru_resize_disable osc
12981         count=10000
12982         echo create $count files
12983         test_mkdir $DIR/$tdir
12984         cancel_lru_locks mdc
12985         cancel_lru_locks osc
12986         t0=$(date +%s)
12987
12988         can0=$(do_facet $SINGLEMDS \
12989                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12990                awk '/ldlm_cancel/ {print $2}')
12991         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12992                awk '/ldlm_bl_callback/ {print $2}')
12993         createmany -o $DIR/$tdir/f $count
12994         sync
12995         can1=$(do_facet $SINGLEMDS \
12996                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12997                awk '/ldlm_cancel/ {print $2}')
12998         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12999                awk '/ldlm_bl_callback/ {print $2}')
13000         t1=$(date +%s)
13001         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13002         echo rm $count files
13003         rm -r $DIR/$tdir
13004         sync
13005         can2=$(do_facet $SINGLEMDS \
13006                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13007                awk '/ldlm_cancel/ {print $2}')
13008         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13009                awk '/ldlm_bl_callback/ {print $2}')
13010         t2=$(date +%s)
13011         echo total: $count removes in $((t2-t1))
13012         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13013         sleep 2
13014         # wait for commitment of removal
13015         lru_resize_enable mdc
13016         lru_resize_enable osc
13017 }
13018 run_test 120g "Early Lock Cancel: performance test"
13019
13020 test_121() { #bug #10589
13021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13022
13023         rm -rf $DIR/$tfile
13024         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13025 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13026         lctl set_param fail_loc=0x310
13027         cancel_lru_locks osc > /dev/null
13028         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13029         lctl set_param fail_loc=0
13030         [[ $reads -eq $writes ]] ||
13031                 error "read $reads blocks, must be $writes blocks"
13032 }
13033 run_test 121 "read cancel race ========="
13034
13035 test_123a_base() { # was test 123, statahead(bug 11401)
13036         local lsx="$1"
13037
13038         SLOWOK=0
13039         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13040                 log "testing UP system. Performance may be lower than expected."
13041                 SLOWOK=1
13042         fi
13043         running_in_vm && SLOWOK=1
13044
13045         rm -rf $DIR/$tdir
13046         test_mkdir $DIR/$tdir
13047         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13048         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13049         MULT=10
13050         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13051                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13052
13053                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13054                 lctl set_param -n llite.*.statahead_max 0
13055                 lctl get_param llite.*.statahead_max
13056                 cancel_lru_locks mdc
13057                 cancel_lru_locks osc
13058                 stime=$(date +%s)
13059                 time $lsx $DIR/$tdir | wc -l
13060                 etime=$(date +%s)
13061                 delta=$((etime - stime))
13062                 log "$lsx $i files without statahead: $delta sec"
13063                 lctl set_param llite.*.statahead_max=$max
13064
13065                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13066                         grep "statahead wrong:" | awk '{print $3}')
13067                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13068                 cancel_lru_locks mdc
13069                 cancel_lru_locks osc
13070                 stime=$(date +%s)
13071                 time $lsx $DIR/$tdir | wc -l
13072                 etime=$(date +%s)
13073                 delta_sa=$((etime - stime))
13074                 log "$lsx $i files with statahead: $delta_sa sec"
13075                 lctl get_param -n llite.*.statahead_stats
13076                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13077                         grep "statahead wrong:" | awk '{print $3}')
13078
13079                 [[ $swrong -lt $ewrong ]] &&
13080                         log "statahead was stopped, maybe too many locks held!"
13081                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13082
13083                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
13084                         max=$(lctl get_param -n llite.*.statahead_max |
13085                                 head -n 1)
13086                         lctl set_param -n llite.*.statahead_max 0
13087                         lctl get_param llite.*.statahead_max
13088                         cancel_lru_locks mdc
13089                         cancel_lru_locks osc
13090                         stime=$(date +%s)
13091                         time $lsx $DIR/$tdir | wc -l
13092                         etime=$(date +%s)
13093                         delta=$((etime - stime))
13094                         log "$lsx $i files again without statahead: $delta sec"
13095                         lctl set_param llite.*.statahead_max=$max
13096                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
13097                                 if [  $SLOWOK -eq 0 ]; then
13098                                         error "$lsx $i files is slower with statahead!"
13099                                 else
13100                                         log "$lsx $i files is slower with statahead!"
13101                                 fi
13102                                 break
13103                         fi
13104                 fi
13105
13106                 [ $delta -gt 20 ] && break
13107                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13108                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13109         done
13110         log "$lsx done"
13111
13112         stime=$(date +%s)
13113         rm -r $DIR/$tdir
13114         sync
13115         etime=$(date +%s)
13116         delta=$((etime - stime))
13117         log "rm -r $DIR/$tdir/: $delta seconds"
13118         log "rm done"
13119         lctl get_param -n llite.*.statahead_stats
13120 }
13121
13122 test_123aa() {
13123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13124
13125         test_123a_base "ls -l"
13126 }
13127 run_test 123aa "verify statahead work"
13128
13129 test_123ab() {
13130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13131
13132         statx_supported || skip_env "Test must be statx() syscall supported"
13133
13134         test_123a_base "$STATX -l"
13135 }
13136 run_test 123ab "verify statahead work by using statx"
13137
13138 test_123ac() {
13139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13140
13141         statx_supported || skip_env "Test must be statx() syscall supported"
13142
13143         local rpcs_before
13144         local rpcs_after
13145         local agl_before
13146         local agl_after
13147
13148         cancel_lru_locks $OSC
13149         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13150         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13151                 awk '/agl.total:/ {print $3}')
13152         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13153         test_123a_base "$STATX --cached=always -D"
13154         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13155                 awk '/agl.total:/ {print $3}')
13156         [ $agl_before -eq $agl_after ] ||
13157                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13158         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13159         [ $rpcs_after -eq $rpcs_before ] ||
13160                 error "$STATX should not send glimpse RPCs to $OSC"
13161 }
13162 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13163
13164 test_123b () { # statahead(bug 15027)
13165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13166
13167         test_mkdir $DIR/$tdir
13168         createmany -o $DIR/$tdir/$tfile-%d 1000
13169
13170         cancel_lru_locks mdc
13171         cancel_lru_locks osc
13172
13173 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13174         lctl set_param fail_loc=0x80000803
13175         ls -lR $DIR/$tdir > /dev/null
13176         log "ls done"
13177         lctl set_param fail_loc=0x0
13178         lctl get_param -n llite.*.statahead_stats
13179         rm -r $DIR/$tdir
13180         sync
13181
13182 }
13183 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13184
13185 test_123c() {
13186         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13187
13188         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13189         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13190         touch $DIR/$tdir.1/{1..3}
13191         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13192
13193         remount_client $MOUNT
13194
13195         $MULTIOP $DIR/$tdir.0 Q
13196
13197         # let statahead to complete
13198         ls -l $DIR/$tdir.0 > /dev/null
13199
13200         testid=$(echo $TESTNAME | tr '_' ' ')
13201         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13202                 error "statahead warning" || true
13203 }
13204 run_test 123c "Can not initialize inode warning on DNE statahead"
13205
13206 test_124a() {
13207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13208         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13209                 skip_env "no lru resize on server"
13210
13211         local NR=2000
13212
13213         test_mkdir $DIR/$tdir
13214
13215         log "create $NR files at $DIR/$tdir"
13216         createmany -o $DIR/$tdir/f $NR ||
13217                 error "failed to create $NR files in $DIR/$tdir"
13218
13219         cancel_lru_locks mdc
13220         ls -l $DIR/$tdir > /dev/null
13221
13222         local NSDIR=""
13223         local LRU_SIZE=0
13224         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13225                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13226                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13227                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13228                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13229                         log "NSDIR=$NSDIR"
13230                         log "NS=$(basename $NSDIR)"
13231                         break
13232                 fi
13233         done
13234
13235         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13236                 skip "Not enough cached locks created!"
13237         fi
13238         log "LRU=$LRU_SIZE"
13239
13240         local SLEEP=30
13241
13242         # We know that lru resize allows one client to hold $LIMIT locks
13243         # for 10h. After that locks begin to be killed by client.
13244         local MAX_HRS=10
13245         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13246         log "LIMIT=$LIMIT"
13247         if [ $LIMIT -lt $LRU_SIZE ]; then
13248                 skip "Limit is too small $LIMIT"
13249         fi
13250
13251         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13252         # killing locks. Some time was spent for creating locks. This means
13253         # that up to the moment of sleep finish we must have killed some of
13254         # them (10-100 locks). This depends on how fast ther were created.
13255         # Many of them were touched in almost the same moment and thus will
13256         # be killed in groups.
13257         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13258
13259         # Use $LRU_SIZE_B here to take into account real number of locks
13260         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13261         local LRU_SIZE_B=$LRU_SIZE
13262         log "LVF=$LVF"
13263         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13264         log "OLD_LVF=$OLD_LVF"
13265         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13266
13267         # Let's make sure that we really have some margin. Client checks
13268         # cached locks every 10 sec.
13269         SLEEP=$((SLEEP+20))
13270         log "Sleep ${SLEEP} sec"
13271         local SEC=0
13272         while ((SEC<$SLEEP)); do
13273                 echo -n "..."
13274                 sleep 5
13275                 SEC=$((SEC+5))
13276                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13277                 echo -n "$LRU_SIZE"
13278         done
13279         echo ""
13280         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13281         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13282
13283         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13284                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13285                 unlinkmany $DIR/$tdir/f $NR
13286                 return
13287         }
13288
13289         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13290         log "unlink $NR files at $DIR/$tdir"
13291         unlinkmany $DIR/$tdir/f $NR
13292 }
13293 run_test 124a "lru resize ======================================="
13294
13295 get_max_pool_limit()
13296 {
13297         local limit=$($LCTL get_param \
13298                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13299         local max=0
13300         for l in $limit; do
13301                 if [[ $l -gt $max ]]; then
13302                         max=$l
13303                 fi
13304         done
13305         echo $max
13306 }
13307
13308 test_124b() {
13309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13310         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13311                 skip_env "no lru resize on server"
13312
13313         LIMIT=$(get_max_pool_limit)
13314
13315         NR=$(($(default_lru_size)*20))
13316         if [[ $NR -gt $LIMIT ]]; then
13317                 log "Limit lock number by $LIMIT locks"
13318                 NR=$LIMIT
13319         fi
13320
13321         IFree=$(mdsrate_inodes_available)
13322         if [ $IFree -lt $NR ]; then
13323                 log "Limit lock number by $IFree inodes"
13324                 NR=$IFree
13325         fi
13326
13327         lru_resize_disable mdc
13328         test_mkdir -p $DIR/$tdir/disable_lru_resize
13329
13330         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13331         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13332         cancel_lru_locks mdc
13333         stime=`date +%s`
13334         PID=""
13335         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13336         PID="$PID $!"
13337         sleep 2
13338         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13339         PID="$PID $!"
13340         sleep 2
13341         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13342         PID="$PID $!"
13343         wait $PID
13344         etime=`date +%s`
13345         nolruresize_delta=$((etime-stime))
13346         log "ls -la time: $nolruresize_delta seconds"
13347         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13348         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13349
13350         lru_resize_enable mdc
13351         test_mkdir -p $DIR/$tdir/enable_lru_resize
13352
13353         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13354         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13355         cancel_lru_locks mdc
13356         stime=`date +%s`
13357         PID=""
13358         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13359         PID="$PID $!"
13360         sleep 2
13361         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13362         PID="$PID $!"
13363         sleep 2
13364         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13365         PID="$PID $!"
13366         wait $PID
13367         etime=`date +%s`
13368         lruresize_delta=$((etime-stime))
13369         log "ls -la time: $lruresize_delta seconds"
13370         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13371
13372         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13373                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13374         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13375                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13376         else
13377                 log "lru resize performs the same with no lru resize"
13378         fi
13379         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13380 }
13381 run_test 124b "lru resize (performance test) ======================="
13382
13383 test_124c() {
13384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13385         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13386                 skip_env "no lru resize on server"
13387
13388         # cache ununsed locks on client
13389         local nr=100
13390         cancel_lru_locks mdc
13391         test_mkdir $DIR/$tdir
13392         createmany -o $DIR/$tdir/f $nr ||
13393                 error "failed to create $nr files in $DIR/$tdir"
13394         ls -l $DIR/$tdir > /dev/null
13395
13396         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13397         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13398         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13399         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13400         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13401
13402         # set lru_max_age to 1 sec
13403         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13404         echo "sleep $((recalc_p * 2)) seconds..."
13405         sleep $((recalc_p * 2))
13406
13407         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13408         # restore lru_max_age
13409         $LCTL set_param -n $nsdir.lru_max_age $max_age
13410         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13411         unlinkmany $DIR/$tdir/f $nr
13412 }
13413 run_test 124c "LRUR cancel very aged locks"
13414
13415 test_124d() {
13416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13417         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13418                 skip_env "no lru resize on server"
13419
13420         # cache ununsed locks on client
13421         local nr=100
13422
13423         lru_resize_disable mdc
13424         stack_trap "lru_resize_enable mdc" EXIT
13425
13426         cancel_lru_locks mdc
13427
13428         # asynchronous object destroy at MDT could cause bl ast to client
13429         test_mkdir $DIR/$tdir
13430         createmany -o $DIR/$tdir/f $nr ||
13431                 error "failed to create $nr files in $DIR/$tdir"
13432         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13433
13434         ls -l $DIR/$tdir > /dev/null
13435
13436         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13437         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13438         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13439         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13440
13441         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13442
13443         # set lru_max_age to 1 sec
13444         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13445         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13446
13447         echo "sleep $((recalc_p * 2)) seconds..."
13448         sleep $((recalc_p * 2))
13449
13450         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13451
13452         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13453 }
13454 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13455
13456 test_125() { # 13358
13457         $LCTL get_param -n llite.*.client_type | grep -q local ||
13458                 skip "must run as local client"
13459         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13460                 skip_env "must have acl enabled"
13461         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13462
13463         test_mkdir $DIR/$tdir
13464         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13465         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13466         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13467 }
13468 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13469
13470 test_126() { # bug 12829/13455
13471         $GSS && skip_env "must run as gss disabled"
13472         $LCTL get_param -n llite.*.client_type | grep -q local ||
13473                 skip "must run as local client"
13474         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13475
13476         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13477         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13478         rm -f $DIR/$tfile
13479         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13480 }
13481 run_test 126 "check that the fsgid provided by the client is taken into account"
13482
13483 test_127a() { # bug 15521
13484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13485         local name count samp unit min max sum sumsq
13486
13487         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13488         echo "stats before reset"
13489         $LCTL get_param osc.*.stats
13490         $LCTL set_param osc.*.stats=0
13491         local fsize=$((2048 * 1024))
13492
13493         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13494         cancel_lru_locks osc
13495         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13496
13497         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13498         stack_trap "rm -f $TMP/$tfile.tmp"
13499         while read name count samp unit min max sum sumsq; do
13500                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13501                 [ ! $min ] && error "Missing min value for $name proc entry"
13502                 eval $name=$count || error "Wrong proc format"
13503
13504                 case $name in
13505                 read_bytes|write_bytes)
13506                         [[ "$unit" =~ "bytes" ]] ||
13507                                 error "unit is not 'bytes': $unit"
13508                         (( $min >= 4096 )) || error "min is too small: $min"
13509                         (( $min <= $fsize )) || error "min is too big: $min"
13510                         (( $max >= 4096 )) || error "max is too small: $max"
13511                         (( $max <= $fsize )) || error "max is too big: $max"
13512                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13513                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13514                                 error "sumsquare is too small: $sumsq"
13515                         (( $sumsq <= $fsize * $fsize )) ||
13516                                 error "sumsquare is too big: $sumsq"
13517                         ;;
13518                 ost_read|ost_write)
13519                         [[ "$unit" =~ "usec" ]] ||
13520                                 error "unit is not 'usec': $unit"
13521                         ;;
13522                 *)      ;;
13523                 esac
13524         done < $DIR/$tfile.tmp
13525
13526         #check that we actually got some stats
13527         [ "$read_bytes" ] || error "Missing read_bytes stats"
13528         [ "$write_bytes" ] || error "Missing write_bytes stats"
13529         [ "$read_bytes" != 0 ] || error "no read done"
13530         [ "$write_bytes" != 0 ] || error "no write done"
13531 }
13532 run_test 127a "verify the client stats are sane"
13533
13534 test_127b() { # bug LU-333
13535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13536         local name count samp unit min max sum sumsq
13537
13538         echo "stats before reset"
13539         $LCTL get_param llite.*.stats
13540         $LCTL set_param llite.*.stats=0
13541
13542         # perform 2 reads and writes so MAX is different from SUM.
13543         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13544         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13545         cancel_lru_locks osc
13546         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13547         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13548
13549         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13550         stack_trap "rm -f $TMP/$tfile.tmp"
13551         while read name count samp unit min max sum sumsq; do
13552                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13553                 eval $name=$count || error "Wrong proc format"
13554
13555                 case $name in
13556                 read_bytes|write_bytes)
13557                         [[ "$unit" =~ "bytes" ]] ||
13558                                 error "unit is not 'bytes': $unit"
13559                         (( $count == 2 )) || error "count is not 2: $count"
13560                         (( $min == $PAGE_SIZE )) ||
13561                                 error "min is not $PAGE_SIZE: $min"
13562                         (( $max == $PAGE_SIZE )) ||
13563                                 error "max is not $PAGE_SIZE: $max"
13564                         (( $sum == $PAGE_SIZE * 2 )) ||
13565                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13566                         ;;
13567                 read|write)
13568                         [[ "$unit" =~ "usec" ]] ||
13569                                 error "unit is not 'usec': $unit"
13570                         ;;
13571                 *)      ;;
13572                 esac
13573         done < $TMP/$tfile.tmp
13574
13575         #check that we actually got some stats
13576         [ "$read_bytes" ] || error "Missing read_bytes stats"
13577         [ "$write_bytes" ] || error "Missing write_bytes stats"
13578         [ "$read_bytes" != 0 ] || error "no read done"
13579         [ "$write_bytes" != 0 ] || error "no write done"
13580 }
13581 run_test 127b "verify the llite client stats are sane"
13582
13583 test_127c() { # LU-12394
13584         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13585         local size
13586         local bsize
13587         local reads
13588         local writes
13589         local count
13590
13591         $LCTL set_param llite.*.extents_stats=1
13592         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13593
13594         # Use two stripes so there is enough space in default config
13595         $LFS setstripe -c 2 $DIR/$tfile
13596
13597         # Extent stats start at 0-4K and go in power of two buckets
13598         # LL_HIST_START = 12 --> 2^12 = 4K
13599         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13600         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13601         # small configs
13602         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13603                 do
13604                 # Write and read, 2x each, second time at a non-zero offset
13605                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13606                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13607                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13608                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13609                 rm -f $DIR/$tfile
13610         done
13611
13612         $LCTL get_param llite.*.extents_stats
13613
13614         count=2
13615         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13616                 do
13617                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13618                                 grep -m 1 $bsize)
13619                 reads=$(echo $bucket | awk '{print $5}')
13620                 writes=$(echo $bucket | awk '{print $9}')
13621                 [ "$reads" -eq $count ] ||
13622                         error "$reads reads in < $bsize bucket, expect $count"
13623                 [ "$writes" -eq $count ] ||
13624                         error "$writes writes in < $bsize bucket, expect $count"
13625         done
13626
13627         # Test mmap write and read
13628         $LCTL set_param llite.*.extents_stats=c
13629         size=512
13630         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13631         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13632         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13633
13634         $LCTL get_param llite.*.extents_stats
13635
13636         count=$(((size*1024) / PAGE_SIZE))
13637
13638         bsize=$((2 * PAGE_SIZE / 1024))K
13639
13640         bucket=$($LCTL get_param -n llite.*.extents_stats |
13641                         grep -m 1 $bsize)
13642         reads=$(echo $bucket | awk '{print $5}')
13643         writes=$(echo $bucket | awk '{print $9}')
13644         # mmap writes fault in the page first, creating an additonal read
13645         [ "$reads" -eq $((2 * count)) ] ||
13646                 error "$reads reads in < $bsize bucket, expect $count"
13647         [ "$writes" -eq $count ] ||
13648                 error "$writes writes in < $bsize bucket, expect $count"
13649 }
13650 run_test 127c "test llite extent stats with regular & mmap i/o"
13651
13652 test_128() { # bug 15212
13653         touch $DIR/$tfile
13654         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13655                 find $DIR/$tfile
13656                 find $DIR/$tfile
13657         EOF
13658
13659         result=$(grep error $TMP/$tfile.log)
13660         rm -f $DIR/$tfile $TMP/$tfile.log
13661         [ -z "$result" ] ||
13662                 error "consecutive find's under interactive lfs failed"
13663 }
13664 run_test 128 "interactive lfs for 2 consecutive find's"
13665
13666 set_dir_limits () {
13667         local mntdev
13668         local canondev
13669         local node
13670
13671         local ldproc=/proc/fs/ldiskfs
13672         local facets=$(get_facets MDS)
13673
13674         for facet in ${facets//,/ }; do
13675                 canondev=$(ldiskfs_canon \
13676                            *.$(convert_facet2label $facet).mntdev $facet)
13677                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13678                         ldproc=/sys/fs/ldiskfs
13679                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13680                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13681         done
13682 }
13683
13684 check_mds_dmesg() {
13685         local facets=$(get_facets MDS)
13686         for facet in ${facets//,/ }; do
13687                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13688         done
13689         return 1
13690 }
13691
13692 test_129() {
13693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13694         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13695                 skip "Need MDS version with at least 2.5.56"
13696         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13697                 skip_env "ldiskfs only test"
13698         fi
13699         remote_mds_nodsh && skip "remote MDS with nodsh"
13700
13701         local ENOSPC=28
13702         local has_warning=false
13703
13704         rm -rf $DIR/$tdir
13705         mkdir -p $DIR/$tdir
13706
13707         # block size of mds1
13708         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13709         set_dir_limits $maxsize $((maxsize * 6 / 8))
13710         stack_trap "set_dir_limits 0 0"
13711         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13712         local dirsize=$(stat -c%s "$DIR/$tdir")
13713         local nfiles=0
13714         while (( $dirsize <= $maxsize )); do
13715                 $MCREATE $DIR/$tdir/file_base_$nfiles
13716                 rc=$?
13717                 # check two errors:
13718                 # ENOSPC for ext4 max_dir_size, which has been used since
13719                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13720                 if (( rc == ENOSPC )); then
13721                         set_dir_limits 0 0
13722                         echo "rc=$rc returned as expected after $nfiles files"
13723
13724                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13725                                 error "create failed w/o dir size limit"
13726
13727                         # messages may be rate limited if test is run repeatedly
13728                         check_mds_dmesg '"is approaching max"' ||
13729                                 echo "warning message should be output"
13730                         check_mds_dmesg '"has reached max"' ||
13731                                 echo "reached message should be output"
13732
13733                         dirsize=$(stat -c%s "$DIR/$tdir")
13734
13735                         [[ $dirsize -ge $maxsize ]] && return 0
13736                         error "dirsize $dirsize < $maxsize after $nfiles files"
13737                 elif (( rc != 0 )); then
13738                         break
13739                 fi
13740                 nfiles=$((nfiles + 1))
13741                 dirsize=$(stat -c%s "$DIR/$tdir")
13742         done
13743
13744         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13745 }
13746 run_test 129 "test directory size limit ========================"
13747
13748 OLDIFS="$IFS"
13749 cleanup_130() {
13750         trap 0
13751         IFS="$OLDIFS"
13752 }
13753
13754 test_130a() {
13755         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13756         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13757
13758         trap cleanup_130 EXIT RETURN
13759
13760         local fm_file=$DIR/$tfile
13761         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13762         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13763                 error "dd failed for $fm_file"
13764
13765         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13766         filefrag -ves $fm_file
13767         RC=$?
13768         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13769                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13770         [ $RC != 0 ] && error "filefrag $fm_file failed"
13771
13772         filefrag_op=$(filefrag -ve -k $fm_file |
13773                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13774         lun=$($LFS getstripe -i $fm_file)
13775
13776         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13777         IFS=$'\n'
13778         tot_len=0
13779         for line in $filefrag_op
13780         do
13781                 frag_lun=`echo $line | cut -d: -f5`
13782                 ext_len=`echo $line | cut -d: -f4`
13783                 if (( $frag_lun != $lun )); then
13784                         cleanup_130
13785                         error "FIEMAP on 1-stripe file($fm_file) failed"
13786                         return
13787                 fi
13788                 (( tot_len += ext_len ))
13789         done
13790
13791         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13792                 cleanup_130
13793                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13794                 return
13795         fi
13796
13797         cleanup_130
13798
13799         echo "FIEMAP on single striped file succeeded"
13800 }
13801 run_test 130a "FIEMAP (1-stripe file)"
13802
13803 test_130b() {
13804         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13805
13806         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13807         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13808
13809         trap cleanup_130 EXIT RETURN
13810
13811         local fm_file=$DIR/$tfile
13812         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13813                         error "setstripe on $fm_file"
13814         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13815                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13816
13817         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13818                 error "dd failed on $fm_file"
13819
13820         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13821         filefrag_op=$(filefrag -ve -k $fm_file |
13822                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13823
13824         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13825                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13826
13827         IFS=$'\n'
13828         tot_len=0
13829         num_luns=1
13830         for line in $filefrag_op
13831         do
13832                 frag_lun=$(echo $line | cut -d: -f5 |
13833                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13834                 ext_len=$(echo $line | cut -d: -f4)
13835                 if (( $frag_lun != $last_lun )); then
13836                         if (( tot_len != 1024 )); then
13837                                 cleanup_130
13838                                 error "FIEMAP on $fm_file failed; returned " \
13839                                 "len $tot_len for OST $last_lun instead of 1024"
13840                                 return
13841                         else
13842                                 (( num_luns += 1 ))
13843                                 tot_len=0
13844                         fi
13845                 fi
13846                 (( tot_len += ext_len ))
13847                 last_lun=$frag_lun
13848         done
13849         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13850                 cleanup_130
13851                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13852                         "luns or wrong len for OST $last_lun"
13853                 return
13854         fi
13855
13856         cleanup_130
13857
13858         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13859 }
13860 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13861
13862 test_130c() {
13863         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13864
13865         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13866         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13867
13868         trap cleanup_130 EXIT RETURN
13869
13870         local fm_file=$DIR/$tfile
13871         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13872         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13873                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13874
13875         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13876                         error "dd failed on $fm_file"
13877
13878         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13879         filefrag_op=$(filefrag -ve -k $fm_file |
13880                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13881
13882         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13883                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13884
13885         IFS=$'\n'
13886         tot_len=0
13887         num_luns=1
13888         for line in $filefrag_op
13889         do
13890                 frag_lun=$(echo $line | cut -d: -f5 |
13891                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13892                 ext_len=$(echo $line | cut -d: -f4)
13893                 if (( $frag_lun != $last_lun )); then
13894                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13895                         if (( logical != 512 )); then
13896                                 cleanup_130
13897                                 error "FIEMAP on $fm_file failed; returned " \
13898                                 "logical start for lun $logical instead of 512"
13899                                 return
13900                         fi
13901                         if (( tot_len != 512 )); then
13902                                 cleanup_130
13903                                 error "FIEMAP on $fm_file failed; returned " \
13904                                 "len $tot_len for OST $last_lun instead of 1024"
13905                                 return
13906                         else
13907                                 (( num_luns += 1 ))
13908                                 tot_len=0
13909                         fi
13910                 fi
13911                 (( tot_len += ext_len ))
13912                 last_lun=$frag_lun
13913         done
13914         if (( num_luns != 2 || tot_len != 512 )); then
13915                 cleanup_130
13916                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13917                         "luns or wrong len for OST $last_lun"
13918                 return
13919         fi
13920
13921         cleanup_130
13922
13923         echo "FIEMAP on 2-stripe file with hole succeeded"
13924 }
13925 run_test 130c "FIEMAP (2-stripe file with hole)"
13926
13927 test_130d() {
13928         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13929
13930         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13931         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13932
13933         trap cleanup_130 EXIT RETURN
13934
13935         local fm_file=$DIR/$tfile
13936         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13937                         error "setstripe on $fm_file"
13938         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13939                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13940
13941         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13942         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13943                 error "dd failed on $fm_file"
13944
13945         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13946         filefrag_op=$(filefrag -ve -k $fm_file |
13947                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13948
13949         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13950                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13951
13952         IFS=$'\n'
13953         tot_len=0
13954         num_luns=1
13955         for line in $filefrag_op
13956         do
13957                 frag_lun=$(echo $line | cut -d: -f5 |
13958                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13959                 ext_len=$(echo $line | cut -d: -f4)
13960                 if (( $frag_lun != $last_lun )); then
13961                         if (( tot_len != 1024 )); then
13962                                 cleanup_130
13963                                 error "FIEMAP on $fm_file failed; returned " \
13964                                 "len $tot_len for OST $last_lun instead of 1024"
13965                                 return
13966                         else
13967                                 (( num_luns += 1 ))
13968                                 tot_len=0
13969                         fi
13970                 fi
13971                 (( tot_len += ext_len ))
13972                 last_lun=$frag_lun
13973         done
13974         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13975                 cleanup_130
13976                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13977                         "luns or wrong len for OST $last_lun"
13978                 return
13979         fi
13980
13981         cleanup_130
13982
13983         echo "FIEMAP on N-stripe file succeeded"
13984 }
13985 run_test 130d "FIEMAP (N-stripe file)"
13986
13987 test_130e() {
13988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13989
13990         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13991         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13992
13993         trap cleanup_130 EXIT RETURN
13994
13995         local fm_file=$DIR/$tfile
13996         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13997
13998         NUM_BLKS=512
13999         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
14000         for ((i = 0; i < $NUM_BLKS; i++)); do
14001                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14002                         conv=notrunc > /dev/null 2>&1
14003         done
14004
14005         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14006         filefrag_op=$(filefrag -ve -k $fm_file |
14007                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14008
14009         last_lun=$(echo $filefrag_op | cut -d: -f5)
14010
14011         IFS=$'\n'
14012         tot_len=0
14013         num_luns=1
14014         for line in $filefrag_op; do
14015                 frag_lun=$(echo $line | cut -d: -f5)
14016                 ext_len=$(echo $line | cut -d: -f4)
14017                 if [[ "$frag_lun" != "$last_lun" ]]; then
14018                         if (( tot_len != $EXPECTED_LEN )); then
14019                                 cleanup_130
14020                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
14021                         else
14022                                 (( num_luns += 1 ))
14023                                 tot_len=0
14024                         fi
14025                 fi
14026                 (( tot_len += ext_len ))
14027                 last_lun=$frag_lun
14028         done
14029         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
14030                 cleanup_130
14031                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
14032         fi
14033
14034         echo "FIEMAP with continuation calls succeeded"
14035 }
14036 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14037
14038 test_130f() {
14039         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14040         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
14041
14042         local fm_file=$DIR/$tfile
14043         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14044                 error "multiop create with lov_delay_create on $fm_file"
14045
14046         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14047         filefrag_extents=$(filefrag -vek $fm_file |
14048                            awk '/extents? found/ { print $2 }')
14049         if [[ "$filefrag_extents" != "0" ]]; then
14050                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14051         fi
14052
14053         rm -f $fm_file
14054 }
14055 run_test 130f "FIEMAP (unstriped file)"
14056
14057 test_130g() {
14058         local file=$DIR/$tfile
14059         local nr=$((OSTCOUNT * 100))
14060
14061         $LFS setstripe -C $nr $file ||
14062                 error "failed to setstripe -C $nr $file"
14063
14064         dd if=/dev/zero of=$file count=$nr bs=1M
14065         sync
14066         nr=$($LFS getstripe -c $file)
14067
14068         local extents=$(filefrag -v $file |
14069                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14070
14071         echo "filefrag list $extents extents in file with stripecount $nr"
14072         if (( extents < nr )); then
14073                 $LFS getstripe $file
14074                 filefrag -v $file
14075                 error "filefrag printed $extents < $nr extents"
14076         fi
14077
14078         rm -f $file
14079 }
14080 run_test 130g "FIEMAP (overstripe file)"
14081
14082 # Test for writev/readv
14083 test_131a() {
14084         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14085                 error "writev test failed"
14086         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14087                 error "readv failed"
14088         rm -f $DIR/$tfile
14089 }
14090 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14091
14092 test_131b() {
14093         local fsize=$((524288 + 1048576 + 1572864))
14094         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14095                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14096                         error "append writev test failed"
14097
14098         ((fsize += 1572864 + 1048576))
14099         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14100                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14101                         error "append writev test failed"
14102         rm -f $DIR/$tfile
14103 }
14104 run_test 131b "test append writev"
14105
14106 test_131c() {
14107         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14108         error "NOT PASS"
14109 }
14110 run_test 131c "test read/write on file w/o objects"
14111
14112 test_131d() {
14113         rwv -f $DIR/$tfile -w -n 1 1572864
14114         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14115         if [ "$NOB" != 1572864 ]; then
14116                 error "Short read filed: read $NOB bytes instead of 1572864"
14117         fi
14118         rm -f $DIR/$tfile
14119 }
14120 run_test 131d "test short read"
14121
14122 test_131e() {
14123         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14124         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14125         error "read hitting hole failed"
14126         rm -f $DIR/$tfile
14127 }
14128 run_test 131e "test read hitting hole"
14129
14130 check_stats() {
14131         local facet=$1
14132         local op=$2
14133         local want=${3:-0}
14134         local res
14135
14136         case $facet in
14137         mds*) res=$(do_facet $facet \
14138                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14139                  ;;
14140         ost*) res=$(do_facet $facet \
14141                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14142                  ;;
14143         *) error "Wrong facet '$facet'" ;;
14144         esac
14145         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14146         # if the argument $3 is zero, it means any stat increment is ok.
14147         if [[ $want -gt 0 ]]; then
14148                 local count=$(echo $res | awk '{ print $2 }')
14149                 [[ $count -ne $want ]] &&
14150                         error "The $op counter on $facet is $count, not $want"
14151         fi
14152 }
14153
14154 test_133a() {
14155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14156         remote_ost_nodsh && skip "remote OST with nodsh"
14157         remote_mds_nodsh && skip "remote MDS with nodsh"
14158         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14159                 skip_env "MDS doesn't support rename stats"
14160
14161         local testdir=$DIR/${tdir}/stats_testdir
14162
14163         mkdir -p $DIR/${tdir}
14164
14165         # clear stats.
14166         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14167         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14168
14169         # verify mdt stats first.
14170         mkdir ${testdir} || error "mkdir failed"
14171         check_stats $SINGLEMDS "mkdir" 1
14172         touch ${testdir}/${tfile} || error "touch failed"
14173         check_stats $SINGLEMDS "open" 1
14174         check_stats $SINGLEMDS "close" 1
14175         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14176                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14177                 check_stats $SINGLEMDS "mknod" 2
14178         }
14179         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14180         check_stats $SINGLEMDS "unlink" 1
14181         rm -f ${testdir}/${tfile} || error "file remove failed"
14182         check_stats $SINGLEMDS "unlink" 2
14183
14184         # remove working dir and check mdt stats again.
14185         rmdir ${testdir} || error "rmdir failed"
14186         check_stats $SINGLEMDS "rmdir" 1
14187
14188         local testdir1=$DIR/${tdir}/stats_testdir1
14189         mkdir -p ${testdir}
14190         mkdir -p ${testdir1}
14191         touch ${testdir1}/test1
14192         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14193         check_stats $SINGLEMDS "crossdir_rename" 1
14194
14195         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14196         check_stats $SINGLEMDS "samedir_rename" 1
14197
14198         rm -rf $DIR/${tdir}
14199 }
14200 run_test 133a "Verifying MDT stats ========================================"
14201
14202 test_133b() {
14203         local res
14204
14205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14206         remote_ost_nodsh && skip "remote OST with nodsh"
14207         remote_mds_nodsh && skip "remote MDS with nodsh"
14208
14209         local testdir=$DIR/${tdir}/stats_testdir
14210
14211         mkdir -p ${testdir} || error "mkdir failed"
14212         touch ${testdir}/${tfile} || error "touch failed"
14213         cancel_lru_locks mdc
14214
14215         # clear stats.
14216         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14217         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14218
14219         # extra mdt stats verification.
14220         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14221         check_stats $SINGLEMDS "setattr" 1
14222         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14223         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14224         then            # LU-1740
14225                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14226                 check_stats $SINGLEMDS "getattr" 1
14227         fi
14228         rm -rf $DIR/${tdir}
14229
14230         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14231         # so the check below is not reliable
14232         [ $MDSCOUNT -eq 1 ] || return 0
14233
14234         # Sleep to avoid a cached response.
14235         #define OBD_STATFS_CACHE_SECONDS 1
14236         sleep 2
14237         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14238         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14239         $LFS df || error "lfs failed"
14240         check_stats $SINGLEMDS "statfs" 1
14241
14242         # check aggregated statfs (LU-10018)
14243         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14244                 return 0
14245         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14246                 return 0
14247         sleep 2
14248         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14249         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14250         df $DIR
14251         check_stats $SINGLEMDS "statfs" 1
14252
14253         # We want to check that the client didn't send OST_STATFS to
14254         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14255         # extra care is needed here.
14256         if remote_mds; then
14257                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14258                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14259
14260                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14261                 [ "$res" ] && error "OST got STATFS"
14262         fi
14263
14264         return 0
14265 }
14266 run_test 133b "Verifying extra MDT stats =================================="
14267
14268 test_133c() {
14269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14270         remote_ost_nodsh && skip "remote OST with nodsh"
14271         remote_mds_nodsh && skip "remote MDS with nodsh"
14272
14273         local testdir=$DIR/$tdir/stats_testdir
14274
14275         test_mkdir -p $testdir
14276
14277         # verify obdfilter stats.
14278         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14279         sync
14280         cancel_lru_locks osc
14281         wait_delete_completed
14282
14283         # clear stats.
14284         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14285         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14286
14287         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14288                 error "dd failed"
14289         sync
14290         cancel_lru_locks osc
14291         check_stats ost1 "write" 1
14292
14293         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14294         check_stats ost1 "read" 1
14295
14296         > $testdir/$tfile || error "truncate failed"
14297         check_stats ost1 "punch" 1
14298
14299         rm -f $testdir/$tfile || error "file remove failed"
14300         wait_delete_completed
14301         check_stats ost1 "destroy" 1
14302
14303         rm -rf $DIR/$tdir
14304 }
14305 run_test 133c "Verifying OST stats ========================================"
14306
14307 order_2() {
14308         local value=$1
14309         local orig=$value
14310         local order=1
14311
14312         while [ $value -ge 2 ]; do
14313                 order=$((order*2))
14314                 value=$((value/2))
14315         done
14316
14317         if [ $orig -gt $order ]; then
14318                 order=$((order*2))
14319         fi
14320         echo $order
14321 }
14322
14323 size_in_KMGT() {
14324     local value=$1
14325     local size=('K' 'M' 'G' 'T');
14326     local i=0
14327     local size_string=$value
14328
14329     while [ $value -ge 1024 ]; do
14330         if [ $i -gt 3 ]; then
14331             #T is the biggest unit we get here, if that is bigger,
14332             #just return XXXT
14333             size_string=${value}T
14334             break
14335         fi
14336         value=$((value >> 10))
14337         if [ $value -lt 1024 ]; then
14338             size_string=${value}${size[$i]}
14339             break
14340         fi
14341         i=$((i + 1))
14342     done
14343
14344     echo $size_string
14345 }
14346
14347 get_rename_size() {
14348         local size=$1
14349         local context=${2:-.}
14350         local sample=$(do_facet $SINGLEMDS $LCTL \
14351                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14352                 grep -A1 $context |
14353                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14354         echo $sample
14355 }
14356
14357 test_133d() {
14358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14359         remote_ost_nodsh && skip "remote OST with nodsh"
14360         remote_mds_nodsh && skip "remote MDS with nodsh"
14361         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14362                 skip_env "MDS doesn't support rename stats"
14363
14364         local testdir1=$DIR/${tdir}/stats_testdir1
14365         local testdir2=$DIR/${tdir}/stats_testdir2
14366         mkdir -p $DIR/${tdir}
14367
14368         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14369
14370         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14371         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14372
14373         createmany -o $testdir1/test 512 || error "createmany failed"
14374
14375         # check samedir rename size
14376         mv ${testdir1}/test0 ${testdir1}/test_0
14377
14378         local testdir1_size=$(ls -l $DIR/${tdir} |
14379                 awk '/stats_testdir1/ {print $5}')
14380         local testdir2_size=$(ls -l $DIR/${tdir} |
14381                 awk '/stats_testdir2/ {print $5}')
14382
14383         testdir1_size=$(order_2 $testdir1_size)
14384         testdir2_size=$(order_2 $testdir2_size)
14385
14386         testdir1_size=$(size_in_KMGT $testdir1_size)
14387         testdir2_size=$(size_in_KMGT $testdir2_size)
14388
14389         echo "source rename dir size: ${testdir1_size}"
14390         echo "target rename dir size: ${testdir2_size}"
14391
14392         local cmd="do_facet $SINGLEMDS $LCTL "
14393         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14394
14395         eval $cmd || error "$cmd failed"
14396         local samedir=$($cmd | grep 'same_dir')
14397         local same_sample=$(get_rename_size $testdir1_size)
14398         [ -z "$samedir" ] && error "samedir_rename_size count error"
14399         [[ $same_sample -eq 1 ]] ||
14400                 error "samedir_rename_size error $same_sample"
14401         echo "Check same dir rename stats success"
14402
14403         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14404
14405         # check crossdir rename size
14406         mv ${testdir1}/test_0 ${testdir2}/test_0
14407
14408         testdir1_size=$(ls -l $DIR/${tdir} |
14409                 awk '/stats_testdir1/ {print $5}')
14410         testdir2_size=$(ls -l $DIR/${tdir} |
14411                 awk '/stats_testdir2/ {print $5}')
14412
14413         testdir1_size=$(order_2 $testdir1_size)
14414         testdir2_size=$(order_2 $testdir2_size)
14415
14416         testdir1_size=$(size_in_KMGT $testdir1_size)
14417         testdir2_size=$(size_in_KMGT $testdir2_size)
14418
14419         echo "source rename dir size: ${testdir1_size}"
14420         echo "target rename dir size: ${testdir2_size}"
14421
14422         eval $cmd || error "$cmd failed"
14423         local crossdir=$($cmd | grep 'crossdir')
14424         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14425         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14426         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14427         [[ $src_sample -eq 1 ]] ||
14428                 error "crossdir_rename_size error $src_sample"
14429         [[ $tgt_sample -eq 1 ]] ||
14430                 error "crossdir_rename_size error $tgt_sample"
14431         echo "Check cross dir rename stats success"
14432         rm -rf $DIR/${tdir}
14433 }
14434 run_test 133d "Verifying rename_stats ========================================"
14435
14436 test_133e() {
14437         remote_mds_nodsh && skip "remote MDS with nodsh"
14438         remote_ost_nodsh && skip "remote OST with nodsh"
14439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14440
14441         local testdir=$DIR/${tdir}/stats_testdir
14442         local ctr f0 f1 bs=32768 count=42 sum
14443
14444         mkdir -p ${testdir} || error "mkdir failed"
14445
14446         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14447
14448         for ctr in {write,read}_bytes; do
14449                 sync
14450                 cancel_lru_locks osc
14451
14452                 do_facet ost1 $LCTL set_param -n \
14453                         "obdfilter.*.exports.clear=clear"
14454
14455                 if [ $ctr = write_bytes ]; then
14456                         f0=/dev/zero
14457                         f1=${testdir}/${tfile}
14458                 else
14459                         f0=${testdir}/${tfile}
14460                         f1=/dev/null
14461                 fi
14462
14463                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14464                         error "dd failed"
14465                 sync
14466                 cancel_lru_locks osc
14467
14468                 sum=$(do_facet ost1 $LCTL get_param \
14469                         "obdfilter.*.exports.*.stats" |
14470                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14471                                 $1 == ctr { sum += $7 }
14472                                 END { printf("%0.0f", sum) }')
14473
14474                 if ((sum != bs * count)); then
14475                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14476                 fi
14477         done
14478
14479         rm -rf $DIR/${tdir}
14480 }
14481 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14482
14483 test_133f() {
14484         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14485                 skip "too old lustre for get_param -R ($facet_ver)"
14486
14487         # verifying readability.
14488         $LCTL get_param -R '*' &> /dev/null
14489
14490         # Verifing writability with badarea_io.
14491         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14492         local skipped_params='force_lbug|changelog_mask|daemon_file'
14493         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14494                 egrep -v "$skipped_params" |
14495                 xargs -n 1 find $proc_dirs -name |
14496                 xargs -n 1 badarea_io ||
14497                 error "client badarea_io failed"
14498
14499         # remount the FS in case writes/reads /proc break the FS
14500         cleanup || error "failed to unmount"
14501         setup || error "failed to setup"
14502 }
14503 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14504
14505 test_133g() {
14506         remote_mds_nodsh && skip "remote MDS with nodsh"
14507         remote_ost_nodsh && skip "remote OST with nodsh"
14508
14509         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14510         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14511         local facet
14512         for facet in mds1 ost1; do
14513                 local facet_ver=$(lustre_version_code $facet)
14514                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14515                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14516                 else
14517                         log "$facet: too old lustre for get_param -R"
14518                 fi
14519                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14520                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14521                                 tr -d = | egrep -v $skipped_params |
14522                                 xargs -n 1 find $proc_dirs -name |
14523                                 xargs -n 1 badarea_io" ||
14524                                         error "$facet badarea_io failed"
14525                 else
14526                         skip_noexit "$facet: too old lustre for get_param -R"
14527                 fi
14528         done
14529
14530         # remount the FS in case writes/reads /proc break the FS
14531         cleanup || error "failed to unmount"
14532         setup || error "failed to setup"
14533 }
14534 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14535
14536 test_133h() {
14537         remote_mds_nodsh && skip "remote MDS with nodsh"
14538         remote_ost_nodsh && skip "remote OST with nodsh"
14539         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14540                 skip "Need MDS version at least 2.9.54"
14541
14542         local facet
14543         for facet in client mds1 ost1; do
14544                 # Get the list of files that are missing the terminating newline
14545                 local plist=$(do_facet $facet
14546                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14547                 local ent
14548                 for ent in $plist; do
14549                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14550                                 awk -v FS='\v' -v RS='\v\v' \
14551                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14552                                         print FILENAME}'" 2>/dev/null)
14553                         [ -z $missing ] || {
14554                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14555                                 error "file does not end with newline: $facet-$ent"
14556                         }
14557                 done
14558         done
14559 }
14560 run_test 133h "Proc files should end with newlines"
14561
14562 test_134a() {
14563         remote_mds_nodsh && skip "remote MDS with nodsh"
14564         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14565                 skip "Need MDS version at least 2.7.54"
14566
14567         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14568         cancel_lru_locks mdc
14569
14570         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14571         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14572         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14573
14574         local nr=1000
14575         createmany -o $DIR/$tdir/f $nr ||
14576                 error "failed to create $nr files in $DIR/$tdir"
14577         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14578
14579         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14580         do_facet mds1 $LCTL set_param fail_loc=0x327
14581         do_facet mds1 $LCTL set_param fail_val=500
14582         touch $DIR/$tdir/m
14583
14584         echo "sleep 10 seconds ..."
14585         sleep 10
14586         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14587
14588         do_facet mds1 $LCTL set_param fail_loc=0
14589         do_facet mds1 $LCTL set_param fail_val=0
14590         [ $lck_cnt -lt $unused ] ||
14591                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14592
14593         rm $DIR/$tdir/m
14594         unlinkmany $DIR/$tdir/f $nr
14595 }
14596 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14597
14598 test_134b() {
14599         remote_mds_nodsh && skip "remote MDS with nodsh"
14600         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14601                 skip "Need MDS version at least 2.7.54"
14602
14603         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14604         cancel_lru_locks mdc
14605
14606         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14607                         ldlm.lock_reclaim_threshold_mb)
14608         # disable reclaim temporarily
14609         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14610
14611         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14612         do_facet mds1 $LCTL set_param fail_loc=0x328
14613         do_facet mds1 $LCTL set_param fail_val=500
14614
14615         $LCTL set_param debug=+trace
14616
14617         local nr=600
14618         createmany -o $DIR/$tdir/f $nr &
14619         local create_pid=$!
14620
14621         echo "Sleep $TIMEOUT seconds ..."
14622         sleep $TIMEOUT
14623         if ! ps -p $create_pid  > /dev/null 2>&1; then
14624                 do_facet mds1 $LCTL set_param fail_loc=0
14625                 do_facet mds1 $LCTL set_param fail_val=0
14626                 do_facet mds1 $LCTL set_param \
14627                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14628                 error "createmany finished incorrectly!"
14629         fi
14630         do_facet mds1 $LCTL set_param fail_loc=0
14631         do_facet mds1 $LCTL set_param fail_val=0
14632         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14633         wait $create_pid || return 1
14634
14635         unlinkmany $DIR/$tdir/f $nr
14636 }
14637 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14638
14639 test_135() {
14640         remote_mds_nodsh && skip "remote MDS with nodsh"
14641         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14642                 skip "Need MDS version at least 2.13.50"
14643         local fname
14644
14645         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14646
14647 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14648         #set only one record at plain llog
14649         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14650
14651         #fill already existed plain llog each 64767
14652         #wrapping whole catalog
14653         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14654
14655         createmany -o $DIR/$tdir/$tfile_ 64700
14656         for (( i = 0; i < 64700; i = i + 2 ))
14657         do
14658                 rm $DIR/$tdir/$tfile_$i &
14659                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14660                 local pid=$!
14661                 wait $pid
14662         done
14663
14664         #waiting osp synchronization
14665         wait_delete_completed
14666 }
14667 run_test 135 "Race catalog processing"
14668
14669 test_136() {
14670         remote_mds_nodsh && skip "remote MDS with nodsh"
14671         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14672                 skip "Need MDS version at least 2.13.50"
14673         local fname
14674
14675         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14676         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14677         #set only one record at plain llog
14678 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14679         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14680
14681         #fill already existed 2 plain llogs each 64767
14682         #wrapping whole catalog
14683         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14684         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14685         wait_delete_completed
14686
14687         createmany -o $DIR/$tdir/$tfile_ 10
14688         sleep 25
14689
14690         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14691         for (( i = 0; i < 10; i = i + 3 ))
14692         do
14693                 rm $DIR/$tdir/$tfile_$i &
14694                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14695                 local pid=$!
14696                 wait $pid
14697                 sleep 7
14698                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14699         done
14700
14701         #waiting osp synchronization
14702         wait_delete_completed
14703 }
14704 run_test 136 "Race catalog processing 2"
14705
14706 test_140() { #bug-17379
14707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14708
14709         test_mkdir $DIR/$tdir
14710         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14711         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14712
14713         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14714         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14715         local i=0
14716         while i=$((i + 1)); do
14717                 test_mkdir $i
14718                 cd $i || error "Changing to $i"
14719                 ln -s ../stat stat || error "Creating stat symlink"
14720                 # Read the symlink until ELOOP present,
14721                 # not LBUGing the system is considered success,
14722                 # we didn't overrun the stack.
14723                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14724                 if [ $ret -ne 0 ]; then
14725                         if [ $ret -eq 40 ]; then
14726                                 break  # -ELOOP
14727                         else
14728                                 error "Open stat symlink"
14729                                         return
14730                         fi
14731                 fi
14732         done
14733         i=$((i - 1))
14734         echo "The symlink depth = $i"
14735         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14736                 error "Invalid symlink depth"
14737
14738         # Test recursive symlink
14739         ln -s symlink_self symlink_self
14740         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14741         echo "open symlink_self returns $ret"
14742         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14743 }
14744 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14745
14746 test_150a() {
14747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14748
14749         local TF="$TMP/$tfile"
14750
14751         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14752         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14753         cp $TF $DIR/$tfile
14754         cancel_lru_locks $OSC
14755         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14756         remount_client $MOUNT
14757         df -P $MOUNT
14758         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14759
14760         $TRUNCATE $TF 6000
14761         $TRUNCATE $DIR/$tfile 6000
14762         cancel_lru_locks $OSC
14763         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14764
14765         echo "12345" >>$TF
14766         echo "12345" >>$DIR/$tfile
14767         cancel_lru_locks $OSC
14768         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14769
14770         echo "12345" >>$TF
14771         echo "12345" >>$DIR/$tfile
14772         cancel_lru_locks $OSC
14773         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14774 }
14775 run_test 150a "truncate/append tests"
14776
14777 test_150b() {
14778         check_set_fallocate_or_skip
14779
14780         touch $DIR/$tfile
14781         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14782         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14783 }
14784 run_test 150b "Verify fallocate (prealloc) functionality"
14785
14786 test_150bb() {
14787         check_set_fallocate_or_skip
14788
14789         touch $DIR/$tfile
14790         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14791         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14792         > $DIR/$tfile
14793         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14794         # precomputed md5sum for 20MB of zeroes
14795         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14796         local sum=($(md5sum $DIR/$tfile))
14797
14798         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14799
14800         check_set_fallocate 1
14801
14802         > $DIR/$tfile
14803         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14804         sum=($(md5sum $DIR/$tfile))
14805
14806         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14807 }
14808 run_test 150bb "Verify fallocate modes both zero space"
14809
14810 test_150c() {
14811         check_set_fallocate_or_skip
14812         local striping="-c2"
14813
14814         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14815         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14816         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14817         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14818         local want=$((OSTCOUNT * 1048576))
14819
14820         # Must allocate all requested space, not more than 5% extra
14821         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14822                 error "bytes $bytes is not $want"
14823
14824         rm -f $DIR/$tfile
14825
14826         echo "verify fallocate on PFL file"
14827
14828         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14829
14830         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14831                 error "Create $DIR/$tfile failed"
14832         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14833         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14834         want=$((512 * 1048576))
14835
14836         # Must allocate all requested space, not more than 5% extra
14837         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14838                 error "bytes $bytes is not $want"
14839 }
14840 run_test 150c "Verify fallocate Size and Blocks"
14841
14842 test_150d() {
14843         check_set_fallocate_or_skip
14844         local striping="-c2"
14845
14846         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14847
14848         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14849         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14850                 error "setstripe failed"
14851         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14852         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14853         local want=$((OSTCOUNT * 1048576))
14854
14855         # Must allocate all requested space, not more than 5% extra
14856         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14857                 error "bytes $bytes is not $want"
14858 }
14859 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14860
14861 test_150e() {
14862         check_set_fallocate_or_skip
14863
14864         echo "df before:"
14865         $LFS df
14866         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14867         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14868                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14869
14870         # Find OST with Minimum Size
14871         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14872                        sort -un | head -1)
14873
14874         # Get 100MB per OST of the available space to reduce run time
14875         # else 60% of the available space if we are running SLOW tests
14876         if [ $SLOW == "no" ]; then
14877                 local space=$((1024 * 100 * OSTCOUNT))
14878         else
14879                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14880         fi
14881
14882         fallocate -l${space}k $DIR/$tfile ||
14883                 error "fallocate ${space}k $DIR/$tfile failed"
14884         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14885
14886         # get size immediately after fallocate. This should be correctly
14887         # updated
14888         local size=$(stat -c '%s' $DIR/$tfile)
14889         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14890
14891         # Sleep for a while for statfs to get updated. And not pull from cache.
14892         sleep 2
14893
14894         echo "df after fallocate:"
14895         $LFS df
14896
14897         (( size / 1024 == space )) || error "size $size != requested $space"
14898         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14899                 error "used $used < space $space"
14900
14901         rm $DIR/$tfile || error "rm failed"
14902         sync
14903         wait_delete_completed
14904
14905         echo "df after unlink:"
14906         $LFS df
14907 }
14908 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14909
14910 test_150f() {
14911         local size
14912         local blocks
14913         local want_size_before=20480 # in bytes
14914         local want_blocks_before=40 # 512 sized blocks
14915         local want_blocks_after=24  # 512 sized blocks
14916         local length=$(((want_blocks_before - want_blocks_after) * 512))
14917
14918         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14919                 skip "need at least 2.14.0 for fallocate punch"
14920
14921         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14922                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14923         fi
14924
14925         check_set_fallocate_or_skip
14926         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14927
14928         [[ "x$DOM" == "xyes" ]] &&
14929                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14930
14931         echo "Verify fallocate punch: Range within the file range"
14932         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14933                 error "dd failed for bs 4096 and count 5"
14934
14935         # Call fallocate with punch range which is within the file range
14936         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14937                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14938         # client must see changes immediately after fallocate
14939         size=$(stat -c '%s' $DIR/$tfile)
14940         blocks=$(stat -c '%b' $DIR/$tfile)
14941
14942         # Verify punch worked.
14943         (( blocks == want_blocks_after )) ||
14944                 error "punch failed: blocks $blocks != $want_blocks_after"
14945
14946         (( size == want_size_before )) ||
14947                 error "punch failed: size $size != $want_size_before"
14948
14949         # Verify there is hole in file
14950         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14951         # precomputed md5sum
14952         local expect="4a9a834a2db02452929c0a348273b4aa"
14953
14954         cksum=($(md5sum $DIR/$tfile))
14955         [[ "${cksum[0]}" == "$expect" ]] ||
14956                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14957
14958         # Start second sub-case for fallocate punch.
14959         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14960         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14961                 error "dd failed for bs 4096 and count 5"
14962
14963         # Punch range less than block size will have no change in block count
14964         want_blocks_after=40  # 512 sized blocks
14965
14966         # Punch overlaps two blocks and less than blocksize
14967         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14968                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14969         size=$(stat -c '%s' $DIR/$tfile)
14970         blocks=$(stat -c '%b' $DIR/$tfile)
14971
14972         # Verify punch worked.
14973         (( blocks == want_blocks_after )) ||
14974                 error "punch failed: blocks $blocks != $want_blocks_after"
14975
14976         (( size == want_size_before )) ||
14977                 error "punch failed: size $size != $want_size_before"
14978
14979         # Verify if range is really zero'ed out. We expect Zeros.
14980         # precomputed md5sum
14981         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14982         cksum=($(md5sum $DIR/$tfile))
14983         [[ "${cksum[0]}" == "$expect" ]] ||
14984                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14985 }
14986 run_test 150f "Verify fallocate punch functionality"
14987
14988 test_150g() {
14989         local space
14990         local size
14991         local blocks
14992         local blocks_after
14993         local size_after
14994         local BS=4096 # Block size in bytes
14995
14996         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14997                 skip "need at least 2.14.0 for fallocate punch"
14998
14999         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15000                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15001         fi
15002
15003         check_set_fallocate_or_skip
15004         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15005
15006         if [[ "x$DOM" == "xyes" ]]; then
15007                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15008                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15009         else
15010                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15011                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15012         fi
15013
15014         # Get 100MB per OST of the available space to reduce run time
15015         # else 60% of the available space if we are running SLOW tests
15016         if [ $SLOW == "no" ]; then
15017                 space=$((1024 * 100 * OSTCOUNT))
15018         else
15019                 # Find OST with Minimum Size
15020                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15021                         sort -un | head -1)
15022                 echo "min size OST: $space"
15023                 space=$(((space * 60)/100 * OSTCOUNT))
15024         fi
15025         # space in 1k units, round to 4k blocks
15026         local blkcount=$((space * 1024 / $BS))
15027
15028         echo "Verify fallocate punch: Very large Range"
15029         fallocate -l${space}k $DIR/$tfile ||
15030                 error "fallocate ${space}k $DIR/$tfile failed"
15031         # write 1M at the end, start and in the middle
15032         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15033                 error "dd failed: bs $BS count 256"
15034         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15035                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15036         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15037                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15038
15039         # Gather stats.
15040         size=$(stat -c '%s' $DIR/$tfile)
15041
15042         # gather punch length.
15043         local punch_size=$((size - (BS * 2)))
15044
15045         echo "punch_size = $punch_size"
15046         echo "size - punch_size: $((size - punch_size))"
15047         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15048
15049         # Call fallocate to punch all except 2 blocks. We leave the
15050         # first and the last block
15051         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15052         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15053                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15054
15055         size_after=$(stat -c '%s' $DIR/$tfile)
15056         blocks_after=$(stat -c '%b' $DIR/$tfile)
15057
15058         # Verify punch worked.
15059         # Size should be kept
15060         (( size == size_after )) ||
15061                 error "punch failed: size $size != $size_after"
15062
15063         # two 4k data blocks to remain plus possible 1 extra extent block
15064         (( blocks_after <= ((BS / 512) * 3) )) ||
15065                 error "too many blocks remains: $blocks_after"
15066
15067         # Verify that file has hole between the first and the last blocks
15068         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15069         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15070
15071         echo "Hole at [$hole_start, $hole_end)"
15072         (( hole_start == BS )) ||
15073                 error "no hole at offset $BS after punch"
15074
15075         (( hole_end == BS + punch_size )) ||
15076                 error "data at offset $hole_end < $((BS + punch_size))"
15077 }
15078 run_test 150g "Verify fallocate punch on large range"
15079
15080 #LU-2902 roc_hit was not able to read all values from lproc
15081 function roc_hit_init() {
15082         local list=$(comma_list $(osts_nodes))
15083         local dir=$DIR/$tdir-check
15084         local file=$dir/$tfile
15085         local BEFORE
15086         local AFTER
15087         local idx
15088
15089         test_mkdir $dir
15090         #use setstripe to do a write to every ost
15091         for i in $(seq 0 $((OSTCOUNT-1))); do
15092                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15093                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15094                 idx=$(printf %04x $i)
15095                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15096                         awk '$1 == "cache_access" {sum += $7}
15097                                 END { printf("%0.0f", sum) }')
15098
15099                 cancel_lru_locks osc
15100                 cat $file >/dev/null
15101
15102                 AFTER=$(get_osd_param $list *OST*$idx stats |
15103                         awk '$1 == "cache_access" {sum += $7}
15104                                 END { printf("%0.0f", sum) }')
15105
15106                 echo BEFORE:$BEFORE AFTER:$AFTER
15107                 if ! let "AFTER - BEFORE == 4"; then
15108                         rm -rf $dir
15109                         error "roc_hit is not safe to use"
15110                 fi
15111                 rm $file
15112         done
15113
15114         rm -rf $dir
15115 }
15116
15117 function roc_hit() {
15118         local list=$(comma_list $(osts_nodes))
15119         echo $(get_osd_param $list '' stats |
15120                 awk '$1 == "cache_hit" {sum += $7}
15121                         END { printf("%0.0f", sum) }')
15122 }
15123
15124 function set_cache() {
15125         local on=1
15126
15127         if [ "$2" == "off" ]; then
15128                 on=0;
15129         fi
15130         local list=$(comma_list $(osts_nodes))
15131         set_osd_param $list '' $1_cache_enable $on
15132
15133         cancel_lru_locks osc
15134 }
15135
15136 test_151() {
15137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15138         remote_ost_nodsh && skip "remote OST with nodsh"
15139
15140         local CPAGES=3
15141         local list=$(comma_list $(osts_nodes))
15142
15143         # check whether obdfilter is cache capable at all
15144         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15145                 skip "not cache-capable obdfilter"
15146         fi
15147
15148         # check cache is enabled on all obdfilters
15149         if get_osd_param $list '' read_cache_enable | grep 0; then
15150                 skip "oss cache is disabled"
15151         fi
15152
15153         set_osd_param $list '' writethrough_cache_enable 1
15154
15155         # check write cache is enabled on all obdfilters
15156         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15157                 skip "oss write cache is NOT enabled"
15158         fi
15159
15160         roc_hit_init
15161
15162         #define OBD_FAIL_OBD_NO_LRU  0x609
15163         do_nodes $list $LCTL set_param fail_loc=0x609
15164
15165         # pages should be in the case right after write
15166         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15167                 error "dd failed"
15168
15169         local BEFORE=$(roc_hit)
15170         cancel_lru_locks osc
15171         cat $DIR/$tfile >/dev/null
15172         local AFTER=$(roc_hit)
15173
15174         do_nodes $list $LCTL set_param fail_loc=0
15175
15176         if ! let "AFTER - BEFORE == CPAGES"; then
15177                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15178         fi
15179
15180         cancel_lru_locks osc
15181         # invalidates OST cache
15182         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15183         set_osd_param $list '' read_cache_enable 0
15184         cat $DIR/$tfile >/dev/null
15185
15186         # now data shouldn't be found in the cache
15187         BEFORE=$(roc_hit)
15188         cancel_lru_locks osc
15189         cat $DIR/$tfile >/dev/null
15190         AFTER=$(roc_hit)
15191         if let "AFTER - BEFORE != 0"; then
15192                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15193         fi
15194
15195         set_osd_param $list '' read_cache_enable 1
15196         rm -f $DIR/$tfile
15197 }
15198 run_test 151 "test cache on oss and controls ==============================="
15199
15200 test_152() {
15201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15202
15203         local TF="$TMP/$tfile"
15204
15205         # simulate ENOMEM during write
15206 #define OBD_FAIL_OST_NOMEM      0x226
15207         lctl set_param fail_loc=0x80000226
15208         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15209         cp $TF $DIR/$tfile
15210         sync || error "sync failed"
15211         lctl set_param fail_loc=0
15212
15213         # discard client's cache
15214         cancel_lru_locks osc
15215
15216         # simulate ENOMEM during read
15217         lctl set_param fail_loc=0x80000226
15218         cmp $TF $DIR/$tfile || error "cmp failed"
15219         lctl set_param fail_loc=0
15220
15221         rm -f $TF
15222 }
15223 run_test 152 "test read/write with enomem ============================"
15224
15225 test_153() {
15226         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15227 }
15228 run_test 153 "test if fdatasync does not crash ======================="
15229
15230 dot_lustre_fid_permission_check() {
15231         local fid=$1
15232         local ffid=$MOUNT/.lustre/fid/$fid
15233         local test_dir=$2
15234
15235         echo "stat fid $fid"
15236         stat $ffid > /dev/null || error "stat $ffid failed."
15237         echo "touch fid $fid"
15238         touch $ffid || error "touch $ffid failed."
15239         echo "write to fid $fid"
15240         cat /etc/hosts > $ffid || error "write $ffid failed."
15241         echo "read fid $fid"
15242         diff /etc/hosts $ffid || error "read $ffid failed."
15243         echo "append write to fid $fid"
15244         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15245         echo "rename fid $fid"
15246         mv $ffid $test_dir/$tfile.1 &&
15247                 error "rename $ffid to $tfile.1 should fail."
15248         touch $test_dir/$tfile.1
15249         mv $test_dir/$tfile.1 $ffid &&
15250                 error "rename $tfile.1 to $ffid should fail."
15251         rm -f $test_dir/$tfile.1
15252         echo "truncate fid $fid"
15253         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15254         echo "link fid $fid"
15255         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15256         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15257                 echo "setfacl fid $fid"
15258                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15259                 echo "getfacl fid $fid"
15260                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15261         fi
15262         echo "unlink fid $fid"
15263         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15264         echo "mknod fid $fid"
15265         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15266
15267         fid=[0xf00000400:0x1:0x0]
15268         ffid=$MOUNT/.lustre/fid/$fid
15269
15270         echo "stat non-exist fid $fid"
15271         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15272         echo "write to non-exist fid $fid"
15273         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15274         echo "link new fid $fid"
15275         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15276
15277         mkdir -p $test_dir/$tdir
15278         touch $test_dir/$tdir/$tfile
15279         fid=$($LFS path2fid $test_dir/$tdir)
15280         rc=$?
15281         [ $rc -ne 0 ] &&
15282                 error "error: could not get fid for $test_dir/$dir/$tfile."
15283
15284         ffid=$MOUNT/.lustre/fid/$fid
15285
15286         echo "ls $fid"
15287         ls $ffid > /dev/null || error "ls $ffid failed."
15288         echo "touch $fid/$tfile.1"
15289         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15290
15291         echo "touch $MOUNT/.lustre/fid/$tfile"
15292         touch $MOUNT/.lustre/fid/$tfile && \
15293                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15294
15295         echo "setxattr to $MOUNT/.lustre/fid"
15296         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15297
15298         echo "listxattr for $MOUNT/.lustre/fid"
15299         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15300
15301         echo "delxattr from $MOUNT/.lustre/fid"
15302         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15303
15304         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15305         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15306                 error "touch invalid fid should fail."
15307
15308         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15309         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15310                 error "touch non-normal fid should fail."
15311
15312         echo "rename $tdir to $MOUNT/.lustre/fid"
15313         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15314                 error "rename to $MOUNT/.lustre/fid should fail."
15315
15316         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15317         then            # LU-3547
15318                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15319                 local new_obf_mode=777
15320
15321                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15322                 chmod $new_obf_mode $DIR/.lustre/fid ||
15323                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15324
15325                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15326                 [ $obf_mode -eq $new_obf_mode ] ||
15327                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15328
15329                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15330                 chmod $old_obf_mode $DIR/.lustre/fid ||
15331                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15332         fi
15333
15334         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15335         fid=$($LFS path2fid $test_dir/$tfile-2)
15336
15337         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15338         then # LU-5424
15339                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15340                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15341                         error "create lov data thru .lustre failed"
15342         fi
15343         echo "cp /etc/passwd $test_dir/$tfile-2"
15344         cp /etc/passwd $test_dir/$tfile-2 ||
15345                 error "copy to $test_dir/$tfile-2 failed."
15346         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15347         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15348                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15349
15350         rm -rf $test_dir/tfile.lnk
15351         rm -rf $test_dir/$tfile-2
15352 }
15353
15354 test_154A() {
15355         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15356                 skip "Need MDS version at least 2.4.1"
15357
15358         local tf=$DIR/$tfile
15359         touch $tf
15360
15361         local fid=$($LFS path2fid $tf)
15362         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15363
15364         # check that we get the same pathname back
15365         local rootpath
15366         local found
15367         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15368                 echo "$rootpath $fid"
15369                 found=$($LFS fid2path $rootpath "$fid")
15370                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15371                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15372         done
15373
15374         # check wrong root path format
15375         rootpath=$MOUNT"_wrong"
15376         found=$($LFS fid2path $rootpath "$fid")
15377         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15378 }
15379 run_test 154A "lfs path2fid and fid2path basic checks"
15380
15381 test_154B() {
15382         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15383                 skip "Need MDS version at least 2.4.1"
15384
15385         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15386         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15387         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15388         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15389
15390         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15391         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15392
15393         # check that we get the same pathname
15394         echo "PFID: $PFID, name: $name"
15395         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15396         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15397         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15398                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15399
15400         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15401 }
15402 run_test 154B "verify the ll_decode_linkea tool"
15403
15404 test_154a() {
15405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15406         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15407         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15408                 skip "Need MDS version at least 2.2.51"
15409         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15410
15411         cp /etc/hosts $DIR/$tfile
15412
15413         fid=$($LFS path2fid $DIR/$tfile)
15414         rc=$?
15415         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15416
15417         dot_lustre_fid_permission_check "$fid" $DIR ||
15418                 error "dot lustre permission check $fid failed"
15419
15420         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15421
15422         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15423
15424         touch $MOUNT/.lustre/file &&
15425                 error "creation is not allowed under .lustre"
15426
15427         mkdir $MOUNT/.lustre/dir &&
15428                 error "mkdir is not allowed under .lustre"
15429
15430         rm -rf $DIR/$tfile
15431 }
15432 run_test 154a "Open-by-FID"
15433
15434 test_154b() {
15435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15436         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15437         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15438         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15439                 skip "Need MDS version at least 2.2.51"
15440
15441         local remote_dir=$DIR/$tdir/remote_dir
15442         local MDTIDX=1
15443         local rc=0
15444
15445         mkdir -p $DIR/$tdir
15446         $LFS mkdir -i $MDTIDX $remote_dir ||
15447                 error "create remote directory failed"
15448
15449         cp /etc/hosts $remote_dir/$tfile
15450
15451         fid=$($LFS path2fid $remote_dir/$tfile)
15452         rc=$?
15453         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15454
15455         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15456                 error "dot lustre permission check $fid failed"
15457         rm -rf $DIR/$tdir
15458 }
15459 run_test 154b "Open-by-FID for remote directory"
15460
15461 test_154c() {
15462         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15463                 skip "Need MDS version at least 2.4.1"
15464
15465         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15466         local FID1=$($LFS path2fid $DIR/$tfile.1)
15467         local FID2=$($LFS path2fid $DIR/$tfile.2)
15468         local FID3=$($LFS path2fid $DIR/$tfile.3)
15469
15470         local N=1
15471         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15472                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15473                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15474                 local want=FID$N
15475                 [ "$FID" = "${!want}" ] ||
15476                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15477                 N=$((N + 1))
15478         done
15479
15480         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15481         do
15482                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15483                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15484                 N=$((N + 1))
15485         done
15486 }
15487 run_test 154c "lfs path2fid and fid2path multiple arguments"
15488
15489 test_154d() {
15490         remote_mds_nodsh && skip "remote MDS with nodsh"
15491         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15492                 skip "Need MDS version at least 2.5.53"
15493
15494         if remote_mds; then
15495                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15496         else
15497                 nid="0@lo"
15498         fi
15499         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15500         local fd
15501         local cmd
15502
15503         rm -f $DIR/$tfile
15504         touch $DIR/$tfile
15505
15506         local fid=$($LFS path2fid $DIR/$tfile)
15507         # Open the file
15508         fd=$(free_fd)
15509         cmd="exec $fd<$DIR/$tfile"
15510         eval $cmd
15511         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15512         echo "$fid_list" | grep "$fid"
15513         rc=$?
15514
15515         cmd="exec $fd>/dev/null"
15516         eval $cmd
15517         if [ $rc -ne 0 ]; then
15518                 error "FID $fid not found in open files list $fid_list"
15519         fi
15520 }
15521 run_test 154d "Verify open file fid"
15522
15523 test_154e()
15524 {
15525         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15526                 skip "Need MDS version at least 2.6.50"
15527
15528         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15529                 error ".lustre returned by readdir"
15530         fi
15531 }
15532 run_test 154e ".lustre is not returned by readdir"
15533
15534 test_154f() {
15535         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15536
15537         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15538         mkdir_on_mdt0 $DIR/$tdir
15539         # test dirs inherit from its stripe
15540         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15541         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15542         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15543         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15544         touch $DIR/f
15545
15546         # get fid of parents
15547         local FID0=$($LFS path2fid $DIR/$tdir)
15548         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15549         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15550         local FID3=$($LFS path2fid $DIR)
15551
15552         # check that path2fid --parents returns expected <parent_fid>/name
15553         # 1) test for a directory (single parent)
15554         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15555         [ "$parent" == "$FID0/foo1" ] ||
15556                 error "expected parent: $FID0/foo1, got: $parent"
15557
15558         # 2) test for a file with nlink > 1 (multiple parents)
15559         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15560         echo "$parent" | grep -F "$FID1/$tfile" ||
15561                 error "$FID1/$tfile not returned in parent list"
15562         echo "$parent" | grep -F "$FID2/link" ||
15563                 error "$FID2/link not returned in parent list"
15564
15565         # 3) get parent by fid
15566         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15567         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15568         echo "$parent" | grep -F "$FID1/$tfile" ||
15569                 error "$FID1/$tfile not returned in parent list (by fid)"
15570         echo "$parent" | grep -F "$FID2/link" ||
15571                 error "$FID2/link not returned in parent list (by fid)"
15572
15573         # 4) test for entry in root directory
15574         parent=$($LFS path2fid --parents $DIR/f)
15575         echo "$parent" | grep -F "$FID3/f" ||
15576                 error "$FID3/f not returned in parent list"
15577
15578         # 5) test it on root directory
15579         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15580                 error "$MOUNT should not have parents"
15581
15582         # enable xattr caching and check that linkea is correctly updated
15583         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15584         save_lustre_params client "llite.*.xattr_cache" > $save
15585         lctl set_param llite.*.xattr_cache 1
15586
15587         # 6.1) linkea update on rename
15588         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15589
15590         # get parents by fid
15591         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15592         # foo1 should no longer be returned in parent list
15593         echo "$parent" | grep -F "$FID1" &&
15594                 error "$FID1 should no longer be in parent list"
15595         # the new path should appear
15596         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15597                 error "$FID2/$tfile.moved is not in parent list"
15598
15599         # 6.2) linkea update on unlink
15600         rm -f $DIR/$tdir/foo2/link
15601         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15602         # foo2/link should no longer be returned in parent list
15603         echo "$parent" | grep -F "$FID2/link" &&
15604                 error "$FID2/link should no longer be in parent list"
15605         true
15606
15607         rm -f $DIR/f
15608         restore_lustre_params < $save
15609         rm -f $save
15610 }
15611 run_test 154f "get parent fids by reading link ea"
15612
15613 test_154g()
15614 {
15615         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15616         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15617            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15618                 skip "Need MDS version at least 2.6.92"
15619
15620         mkdir_on_mdt0 $DIR/$tdir
15621         llapi_fid_test -d $DIR/$tdir
15622 }
15623 run_test 154g "various llapi FID tests"
15624
15625 test_155_small_load() {
15626     local temp=$TMP/$tfile
15627     local file=$DIR/$tfile
15628
15629     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15630         error "dd of=$temp bs=6096 count=1 failed"
15631     cp $temp $file
15632     cancel_lru_locks $OSC
15633     cmp $temp $file || error "$temp $file differ"
15634
15635     $TRUNCATE $temp 6000
15636     $TRUNCATE $file 6000
15637     cmp $temp $file || error "$temp $file differ (truncate1)"
15638
15639     echo "12345" >>$temp
15640     echo "12345" >>$file
15641     cmp $temp $file || error "$temp $file differ (append1)"
15642
15643     echo "12345" >>$temp
15644     echo "12345" >>$file
15645     cmp $temp $file || error "$temp $file differ (append2)"
15646
15647     rm -f $temp $file
15648     true
15649 }
15650
15651 test_155_big_load() {
15652         remote_ost_nodsh && skip "remote OST with nodsh"
15653
15654         local temp=$TMP/$tfile
15655         local file=$DIR/$tfile
15656
15657         free_min_max
15658         local cache_size=$(do_facet ost$((MAXI+1)) \
15659                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15660         local large_file_size=$((cache_size * 2))
15661
15662         echo "OSS cache size: $cache_size KB"
15663         echo "Large file size: $large_file_size KB"
15664
15665         [ $MAXV -le $large_file_size ] &&
15666                 skip_env "max available OST size needs > $large_file_size KB"
15667
15668         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15669
15670         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15671                 error "dd of=$temp bs=$large_file_size count=1k failed"
15672         cp $temp $file
15673         ls -lh $temp $file
15674         cancel_lru_locks osc
15675         cmp $temp $file || error "$temp $file differ"
15676
15677         rm -f $temp $file
15678         true
15679 }
15680
15681 save_writethrough() {
15682         local facets=$(get_facets OST)
15683
15684         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15685 }
15686
15687 test_155a() {
15688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15689
15690         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15691
15692         save_writethrough $p
15693
15694         set_cache read on
15695         set_cache writethrough on
15696         test_155_small_load
15697         restore_lustre_params < $p
15698         rm -f $p
15699 }
15700 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15701
15702 test_155b() {
15703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15704
15705         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15706
15707         save_writethrough $p
15708
15709         set_cache read on
15710         set_cache writethrough off
15711         test_155_small_load
15712         restore_lustre_params < $p
15713         rm -f $p
15714 }
15715 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15716
15717 test_155c() {
15718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15719
15720         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15721
15722         save_writethrough $p
15723
15724         set_cache read off
15725         set_cache writethrough on
15726         test_155_small_load
15727         restore_lustre_params < $p
15728         rm -f $p
15729 }
15730 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15731
15732 test_155d() {
15733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15734
15735         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15736
15737         save_writethrough $p
15738
15739         set_cache read off
15740         set_cache writethrough off
15741         test_155_small_load
15742         restore_lustre_params < $p
15743         rm -f $p
15744 }
15745 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15746
15747 test_155e() {
15748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15749
15750         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15751
15752         save_writethrough $p
15753
15754         set_cache read on
15755         set_cache writethrough on
15756         test_155_big_load
15757         restore_lustre_params < $p
15758         rm -f $p
15759 }
15760 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15761
15762 test_155f() {
15763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15764
15765         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15766
15767         save_writethrough $p
15768
15769         set_cache read on
15770         set_cache writethrough off
15771         test_155_big_load
15772         restore_lustre_params < $p
15773         rm -f $p
15774 }
15775 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15776
15777 test_155g() {
15778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15779
15780         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15781
15782         save_writethrough $p
15783
15784         set_cache read off
15785         set_cache writethrough on
15786         test_155_big_load
15787         restore_lustre_params < $p
15788         rm -f $p
15789 }
15790 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15791
15792 test_155h() {
15793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15794
15795         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15796
15797         save_writethrough $p
15798
15799         set_cache read off
15800         set_cache writethrough off
15801         test_155_big_load
15802         restore_lustre_params < $p
15803         rm -f $p
15804 }
15805 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15806
15807 test_156() {
15808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15809         remote_ost_nodsh && skip "remote OST with nodsh"
15810         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15811                 skip "stats not implemented on old servers"
15812         [ "$ost1_FSTYPE" = "zfs" ] &&
15813                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15814
15815         local CPAGES=3
15816         local BEFORE
15817         local AFTER
15818         local file="$DIR/$tfile"
15819         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15820
15821         save_writethrough $p
15822         roc_hit_init
15823
15824         log "Turn on read and write cache"
15825         set_cache read on
15826         set_cache writethrough on
15827
15828         log "Write data and read it back."
15829         log "Read should be satisfied from the cache."
15830         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15831         BEFORE=$(roc_hit)
15832         cancel_lru_locks osc
15833         cat $file >/dev/null
15834         AFTER=$(roc_hit)
15835         if ! let "AFTER - BEFORE == CPAGES"; then
15836                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15837         else
15838                 log "cache hits: before: $BEFORE, after: $AFTER"
15839         fi
15840
15841         log "Read again; it should be satisfied from the cache."
15842         BEFORE=$AFTER
15843         cancel_lru_locks osc
15844         cat $file >/dev/null
15845         AFTER=$(roc_hit)
15846         if ! let "AFTER - BEFORE == CPAGES"; then
15847                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15848         else
15849                 log "cache hits:: before: $BEFORE, after: $AFTER"
15850         fi
15851
15852         log "Turn off the read cache and turn on the write cache"
15853         set_cache read off
15854         set_cache writethrough on
15855
15856         log "Read again; it should be satisfied from the cache."
15857         BEFORE=$(roc_hit)
15858         cancel_lru_locks osc
15859         cat $file >/dev/null
15860         AFTER=$(roc_hit)
15861         if ! let "AFTER - BEFORE == CPAGES"; then
15862                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15863         else
15864                 log "cache hits:: before: $BEFORE, after: $AFTER"
15865         fi
15866
15867         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15868                 # > 2.12.56 uses pagecache if cached
15869                 log "Read again; it should not be satisfied from the cache."
15870                 BEFORE=$AFTER
15871                 cancel_lru_locks osc
15872                 cat $file >/dev/null
15873                 AFTER=$(roc_hit)
15874                 if ! let "AFTER - BEFORE == 0"; then
15875                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15876                 else
15877                         log "cache hits:: before: $BEFORE, after: $AFTER"
15878                 fi
15879         fi
15880
15881         log "Write data and read it back."
15882         log "Read should be satisfied from the cache."
15883         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15884         BEFORE=$(roc_hit)
15885         cancel_lru_locks osc
15886         cat $file >/dev/null
15887         AFTER=$(roc_hit)
15888         if ! let "AFTER - BEFORE == CPAGES"; then
15889                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15890         else
15891                 log "cache hits:: before: $BEFORE, after: $AFTER"
15892         fi
15893
15894         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15895                 # > 2.12.56 uses pagecache if cached
15896                 log "Read again; it should not be satisfied from the cache."
15897                 BEFORE=$AFTER
15898                 cancel_lru_locks osc
15899                 cat $file >/dev/null
15900                 AFTER=$(roc_hit)
15901                 if ! let "AFTER - BEFORE == 0"; then
15902                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15903                 else
15904                         log "cache hits:: before: $BEFORE, after: $AFTER"
15905                 fi
15906         fi
15907
15908         log "Turn off read and write cache"
15909         set_cache read off
15910         set_cache writethrough off
15911
15912         log "Write data and read it back"
15913         log "It should not be satisfied from the cache."
15914         rm -f $file
15915         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15916         cancel_lru_locks osc
15917         BEFORE=$(roc_hit)
15918         cat $file >/dev/null
15919         AFTER=$(roc_hit)
15920         if ! let "AFTER - BEFORE == 0"; then
15921                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15922         else
15923                 log "cache hits:: before: $BEFORE, after: $AFTER"
15924         fi
15925
15926         log "Turn on the read cache and turn off the write cache"
15927         set_cache read on
15928         set_cache writethrough off
15929
15930         log "Write data and read it back"
15931         log "It should not be satisfied from the cache."
15932         rm -f $file
15933         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15934         BEFORE=$(roc_hit)
15935         cancel_lru_locks osc
15936         cat $file >/dev/null
15937         AFTER=$(roc_hit)
15938         if ! let "AFTER - BEFORE == 0"; then
15939                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15940         else
15941                 log "cache hits:: before: $BEFORE, after: $AFTER"
15942         fi
15943
15944         log "Read again; it should be satisfied from the cache."
15945         BEFORE=$(roc_hit)
15946         cancel_lru_locks osc
15947         cat $file >/dev/null
15948         AFTER=$(roc_hit)
15949         if ! let "AFTER - BEFORE == CPAGES"; then
15950                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15951         else
15952                 log "cache hits:: before: $BEFORE, after: $AFTER"
15953         fi
15954
15955         restore_lustre_params < $p
15956         rm -f $p $file
15957 }
15958 run_test 156 "Verification of tunables"
15959
15960 test_160a() {
15961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15962         remote_mds_nodsh && skip "remote MDS with nodsh"
15963         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15964                 skip "Need MDS version at least 2.2.0"
15965
15966         changelog_register || error "changelog_register failed"
15967         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15968         changelog_users $SINGLEMDS | grep -q $cl_user ||
15969                 error "User $cl_user not found in changelog_users"
15970
15971         mkdir_on_mdt0 $DIR/$tdir
15972
15973         # change something
15974         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15975         changelog_clear 0 || error "changelog_clear failed"
15976         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15977         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15978         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15979         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15980         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15981         rm $DIR/$tdir/pics/desktop.jpg
15982
15983         echo "verifying changelog mask"
15984         changelog_chmask "-MKDIR"
15985         changelog_chmask "-CLOSE"
15986
15987         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15988         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15989
15990         changelog_chmask "+MKDIR"
15991         changelog_chmask "+CLOSE"
15992
15993         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15994         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15995
15996         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15997         CLOSES=$(changelog_dump | grep -c "CLOSE")
15998         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15999         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16000
16001         # verify contents
16002         echo "verifying target fid"
16003         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16004         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16005         [ "$fidc" == "$fidf" ] ||
16006                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16007         echo "verifying parent fid"
16008         # The FID returned from the Changelog may be the directory shard on
16009         # a different MDT, and not the FID returned by path2fid on the parent.
16010         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16011         # since this is what will matter when recreating this file in the tree.
16012         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16013         local pathp=$($LFS fid2path $MOUNT "$fidp")
16014         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16015                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16016
16017         echo "getting records for $cl_user"
16018         changelog_users $SINGLEMDS
16019         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16020         local nclr=3
16021         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16022                 error "changelog_clear failed"
16023         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16024         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16025         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16026                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16027
16028         local min0_rec=$(changelog_users $SINGLEMDS |
16029                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16030         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16031                           awk '{ print $1; exit; }')
16032
16033         changelog_dump | tail -n 5
16034         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16035         [ $first_rec == $((min0_rec + 1)) ] ||
16036                 error "first index should be $min0_rec + 1 not $first_rec"
16037
16038         # LU-3446 changelog index reset on MDT restart
16039         local cur_rec1=$(changelog_users $SINGLEMDS |
16040                          awk '/^current.index:/ { print $NF }')
16041         changelog_clear 0 ||
16042                 error "clear all changelog records for $cl_user failed"
16043         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16044         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16045                 error "Fail to start $SINGLEMDS"
16046         local cur_rec2=$(changelog_users $SINGLEMDS |
16047                          awk '/^current.index:/ { print $NF }')
16048         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16049         [ $cur_rec1 == $cur_rec2 ] ||
16050                 error "current index should be $cur_rec1 not $cur_rec2"
16051
16052         echo "verifying users from this test are deregistered"
16053         changelog_deregister || error "changelog_deregister failed"
16054         changelog_users $SINGLEMDS | grep -q $cl_user &&
16055                 error "User '$cl_user' still in changelog_users"
16056
16057         # lctl get_param -n mdd.*.changelog_users
16058         # current_index: 144
16059         # ID    index (idle seconds)
16060         # cl3   144   (2) mask=<list>
16061         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16062                 # this is the normal case where all users were deregistered
16063                 # make sure no new records are added when no users are present
16064                 local last_rec1=$(changelog_users $SINGLEMDS |
16065                                   awk '/^current.index:/ { print $NF }')
16066                 touch $DIR/$tdir/chloe
16067                 local last_rec2=$(changelog_users $SINGLEMDS |
16068                                   awk '/^current.index:/ { print $NF }')
16069                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16070                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16071         else
16072                 # any changelog users must be leftovers from a previous test
16073                 changelog_users $SINGLEMDS
16074                 echo "other changelog users; can't verify off"
16075         fi
16076 }
16077 run_test 160a "changelog sanity"
16078
16079 test_160b() { # LU-3587
16080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16081         remote_mds_nodsh && skip "remote MDS with nodsh"
16082         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16083                 skip "Need MDS version at least 2.2.0"
16084
16085         changelog_register || error "changelog_register failed"
16086         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16087         changelog_users $SINGLEMDS | grep -q $cl_user ||
16088                 error "User '$cl_user' not found in changelog_users"
16089
16090         local longname1=$(str_repeat a 255)
16091         local longname2=$(str_repeat b 255)
16092
16093         cd $DIR
16094         echo "creating very long named file"
16095         touch $longname1 || error "create of '$longname1' failed"
16096         echo "renaming very long named file"
16097         mv $longname1 $longname2
16098
16099         changelog_dump | grep RENME | tail -n 5
16100         rm -f $longname2
16101 }
16102 run_test 160b "Verify that very long rename doesn't crash in changelog"
16103
16104 test_160c() {
16105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16106         remote_mds_nodsh && skip "remote MDS with nodsh"
16107
16108         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16109                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16110                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16111                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16112
16113         local rc=0
16114
16115         # Registration step
16116         changelog_register || error "changelog_register failed"
16117
16118         rm -rf $DIR/$tdir
16119         mkdir -p $DIR/$tdir
16120         $MCREATE $DIR/$tdir/foo_160c
16121         changelog_chmask "-TRUNC"
16122         $TRUNCATE $DIR/$tdir/foo_160c 200
16123         changelog_chmask "+TRUNC"
16124         $TRUNCATE $DIR/$tdir/foo_160c 199
16125         changelog_dump | tail -n 5
16126         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16127         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16128 }
16129 run_test 160c "verify that changelog log catch the truncate event"
16130
16131 test_160d() {
16132         remote_mds_nodsh && skip "remote MDS with nodsh"
16133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16135         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16136                 skip "Need MDS version at least 2.7.60"
16137
16138         # Registration step
16139         changelog_register || error "changelog_register failed"
16140
16141         mkdir -p $DIR/$tdir/migrate_dir
16142         changelog_clear 0 || error "changelog_clear failed"
16143
16144         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16145         changelog_dump | tail -n 5
16146         local migrates=$(changelog_dump | grep -c "MIGRT")
16147         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16148 }
16149 run_test 160d "verify that changelog log catch the migrate event"
16150
16151 test_160e() {
16152         remote_mds_nodsh && skip "remote MDS with nodsh"
16153
16154         # Create a user
16155         changelog_register || error "changelog_register failed"
16156
16157         local MDT0=$(facet_svc $SINGLEMDS)
16158         local rc
16159
16160         # No user (expect fail)
16161         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16162         rc=$?
16163         if [ $rc -eq 0 ]; then
16164                 error "Should fail without user"
16165         elif [ $rc -ne 4 ]; then
16166                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16167         fi
16168
16169         # Delete a future user (expect fail)
16170         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16171         rc=$?
16172         if [ $rc -eq 0 ]; then
16173                 error "Deleted non-existant user cl77"
16174         elif [ $rc -ne 2 ]; then
16175                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16176         fi
16177
16178         # Clear to a bad index (1 billion should be safe)
16179         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16180         rc=$?
16181
16182         if [ $rc -eq 0 ]; then
16183                 error "Successfully cleared to invalid CL index"
16184         elif [ $rc -ne 22 ]; then
16185                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16186         fi
16187 }
16188 run_test 160e "changelog negative testing (should return errors)"
16189
16190 test_160f() {
16191         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16192         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16193                 skip "Need MDS version at least 2.10.56"
16194
16195         local mdts=$(comma_list $(mdts_nodes))
16196
16197         # Create a user
16198         changelog_register || error "first changelog_register failed"
16199         changelog_register || error "second changelog_register failed"
16200         local cl_users
16201         declare -A cl_user1
16202         declare -A cl_user2
16203         local user_rec1
16204         local user_rec2
16205         local i
16206
16207         # generate some changelog records to accumulate on each MDT
16208         # use all_char because created files should be evenly distributed
16209         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16210                 error "test_mkdir $tdir failed"
16211         log "$(date +%s): creating first files"
16212         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16213                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16214                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16215         done
16216
16217         # check changelogs have been generated
16218         local start=$SECONDS
16219         local idle_time=$((MDSCOUNT * 5 + 5))
16220         local nbcl=$(changelog_dump | wc -l)
16221         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16222
16223         for param in "changelog_max_idle_time=$idle_time" \
16224                      "changelog_gc=1" \
16225                      "changelog_min_gc_interval=2" \
16226                      "changelog_min_free_cat_entries=3"; do
16227                 local MDT0=$(facet_svc $SINGLEMDS)
16228                 local var="${param%=*}"
16229                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16230
16231                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16232                 do_nodes $mdts $LCTL set_param mdd.*.$param
16233         done
16234
16235         # force cl_user2 to be idle (1st part), but also cancel the
16236         # cl_user1 records so that it is not evicted later in the test.
16237         local sleep1=$((idle_time / 2))
16238         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16239         sleep $sleep1
16240
16241         # simulate changelog catalog almost full
16242         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16243         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16244
16245         for i in $(seq $MDSCOUNT); do
16246                 cl_users=(${CL_USERS[mds$i]})
16247                 cl_user1[mds$i]="${cl_users[0]}"
16248                 cl_user2[mds$i]="${cl_users[1]}"
16249
16250                 [ -n "${cl_user1[mds$i]}" ] ||
16251                         error "mds$i: no user registered"
16252                 [ -n "${cl_user2[mds$i]}" ] ||
16253                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16254
16255                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16256                 [ -n "$user_rec1" ] ||
16257                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16258                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16259                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16260                 [ -n "$user_rec2" ] ||
16261                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16262                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16263                      "$user_rec1 + 2 == $user_rec2"
16264                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16265                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16266                               "$user_rec1 + 2, but is $user_rec2"
16267                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16268                 [ -n "$user_rec2" ] ||
16269                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16270                 [ $user_rec1 == $user_rec2 ] ||
16271                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16272                               "$user_rec1, but is $user_rec2"
16273         done
16274
16275         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16276         local sleep2=$((idle_time - (SECONDS - start) + 1))
16277         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16278         sleep $sleep2
16279
16280         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16281         # cl_user1 should be OK because it recently processed records.
16282         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16283         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16284                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16285                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16286         done
16287
16288         # ensure gc thread is done
16289         for i in $(mdts_nodes); do
16290                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16291                         error "$i: GC-thread not done"
16292         done
16293
16294         local first_rec
16295         for (( i = 1; i <= MDSCOUNT; i++ )); do
16296                 # check cl_user1 still registered
16297                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16298                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16299                 # check cl_user2 unregistered
16300                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16301                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16302
16303                 # check changelogs are present and starting at $user_rec1 + 1
16304                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16305                 [ -n "$user_rec1" ] ||
16306                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16307                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16308                             awk '{ print $1; exit; }')
16309
16310                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16311                 [ $((user_rec1 + 1)) == $first_rec ] ||
16312                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16313         done
16314 }
16315 run_test 160f "changelog garbage collect (timestamped users)"
16316
16317 test_160g() {
16318         remote_mds_nodsh && skip "remote MDS with nodsh"
16319         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16320                 skip "Need MDS version at least 2.14.55"
16321
16322         local mdts=$(comma_list $(mdts_nodes))
16323
16324         # Create a user
16325         changelog_register || error "first changelog_register failed"
16326         changelog_register || error "second changelog_register failed"
16327         local cl_users
16328         declare -A cl_user1
16329         declare -A cl_user2
16330         local user_rec1
16331         local user_rec2
16332         local i
16333
16334         # generate some changelog records to accumulate on each MDT
16335         # use all_char because created files should be evenly distributed
16336         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16337                 error "test_mkdir $tdir failed"
16338         for ((i = 0; i < MDSCOUNT; i++)); do
16339                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16340                         error "create $DIR/$tdir/d$i.1 failed"
16341         done
16342
16343         # check changelogs have been generated
16344         local nbcl=$(changelog_dump | wc -l)
16345         (( $nbcl > 0 )) || error "no changelogs found"
16346
16347         # reduce the max_idle_indexes value to make sure we exceed it
16348         for param in "changelog_max_idle_indexes=2" \
16349                      "changelog_gc=1" \
16350                      "changelog_min_gc_interval=2"; do
16351                 local MDT0=$(facet_svc $SINGLEMDS)
16352                 local var="${param%=*}"
16353                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16354
16355                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16356                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16357                         error "unable to set mdd.*.$param"
16358         done
16359
16360         local start=$SECONDS
16361         for i in $(seq $MDSCOUNT); do
16362                 cl_users=(${CL_USERS[mds$i]})
16363                 cl_user1[mds$i]="${cl_users[0]}"
16364                 cl_user2[mds$i]="${cl_users[1]}"
16365
16366                 [ -n "${cl_user1[mds$i]}" ] ||
16367                         error "mds$i: user1 is not registered"
16368                 [ -n "${cl_user2[mds$i]}" ] ||
16369                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16370
16371                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16372                 [ -n "$user_rec1" ] ||
16373                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16374                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16375                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16376                 [ -n "$user_rec2" ] ||
16377                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16378                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16379                      "$user_rec1 + 2 == $user_rec2"
16380                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16381                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16382                               "expected $user_rec1 + 2, but is $user_rec2"
16383                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16384                 [ -n "$user_rec2" ] ||
16385                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16386                 [ $user_rec1 == $user_rec2 ] ||
16387                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16388                               "expected $user_rec1, but is $user_rec2"
16389         done
16390
16391         # ensure we are past the previous changelog_min_gc_interval set above
16392         local sleep2=$((start + 2 - SECONDS))
16393         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16394         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16395         # cl_user1 should be OK because it recently processed records.
16396         for ((i = 0; i < MDSCOUNT; i++)); do
16397                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16398                         error "create $DIR/$tdir/d$i.3 failed"
16399         done
16400
16401         # ensure gc thread is done
16402         for i in $(mdts_nodes); do
16403                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16404                         error "$i: GC-thread not done"
16405         done
16406
16407         local first_rec
16408         for (( i = 1; i <= MDSCOUNT; i++ )); do
16409                 # check cl_user1 still registered
16410                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16411                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16412                 # check cl_user2 unregistered
16413                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16414                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16415
16416                 # check changelogs are present and starting at $user_rec1 + 1
16417                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16418                 [ -n "$user_rec1" ] ||
16419                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16420                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16421                             awk '{ print $1; exit; }')
16422
16423                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16424                 [ $((user_rec1 + 1)) == $first_rec ] ||
16425                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16426         done
16427 }
16428 run_test 160g "changelog garbage collect on idle records"
16429
16430 test_160h() {
16431         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16432         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16433                 skip "Need MDS version at least 2.10.56"
16434
16435         local mdts=$(comma_list $(mdts_nodes))
16436
16437         # Create a user
16438         changelog_register || error "first changelog_register failed"
16439         changelog_register || error "second changelog_register failed"
16440         local cl_users
16441         declare -A cl_user1
16442         declare -A cl_user2
16443         local user_rec1
16444         local user_rec2
16445         local i
16446
16447         # generate some changelog records to accumulate on each MDT
16448         # use all_char because created files should be evenly distributed
16449         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16450                 error "test_mkdir $tdir failed"
16451         for ((i = 0; i < MDSCOUNT; i++)); do
16452                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16453                         error "create $DIR/$tdir/d$i.1 failed"
16454         done
16455
16456         # check changelogs have been generated
16457         local nbcl=$(changelog_dump | wc -l)
16458         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16459
16460         for param in "changelog_max_idle_time=10" \
16461                      "changelog_gc=1" \
16462                      "changelog_min_gc_interval=2"; do
16463                 local MDT0=$(facet_svc $SINGLEMDS)
16464                 local var="${param%=*}"
16465                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16466
16467                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16468                 do_nodes $mdts $LCTL set_param mdd.*.$param
16469         done
16470
16471         # force cl_user2 to be idle (1st part)
16472         sleep 9
16473
16474         for i in $(seq $MDSCOUNT); do
16475                 cl_users=(${CL_USERS[mds$i]})
16476                 cl_user1[mds$i]="${cl_users[0]}"
16477                 cl_user2[mds$i]="${cl_users[1]}"
16478
16479                 [ -n "${cl_user1[mds$i]}" ] ||
16480                         error "mds$i: no user registered"
16481                 [ -n "${cl_user2[mds$i]}" ] ||
16482                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16483
16484                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16485                 [ -n "$user_rec1" ] ||
16486                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16487                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16488                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16489                 [ -n "$user_rec2" ] ||
16490                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16491                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16492                      "$user_rec1 + 2 == $user_rec2"
16493                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16494                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16495                               "$user_rec1 + 2, but is $user_rec2"
16496                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16497                 [ -n "$user_rec2" ] ||
16498                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16499                 [ $user_rec1 == $user_rec2 ] ||
16500                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16501                               "$user_rec1, but is $user_rec2"
16502         done
16503
16504         # force cl_user2 to be idle (2nd part) and to reach
16505         # changelog_max_idle_time
16506         sleep 2
16507
16508         # force each GC-thread start and block then
16509         # one per MDT/MDD, set fail_val accordingly
16510         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16511         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16512
16513         # generate more changelogs to trigger fail_loc
16514         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16515                 error "create $DIR/$tdir/${tfile}bis failed"
16516
16517         # stop MDT to stop GC-thread, should be done in back-ground as it will
16518         # block waiting for the thread to be released and exit
16519         declare -A stop_pids
16520         for i in $(seq $MDSCOUNT); do
16521                 stop mds$i &
16522                 stop_pids[mds$i]=$!
16523         done
16524
16525         for i in $(mdts_nodes); do
16526                 local facet
16527                 local nb=0
16528                 local facets=$(facets_up_on_host $i)
16529
16530                 for facet in ${facets//,/ }; do
16531                         if [[ $facet == mds* ]]; then
16532                                 nb=$((nb + 1))
16533                         fi
16534                 done
16535                 # ensure each MDS's gc threads are still present and all in "R"
16536                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16537                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16538                         error "$i: expected $nb GC-thread"
16539                 wait_update $i \
16540                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16541                         "R" 20 ||
16542                         error "$i: GC-thread not found in R-state"
16543                 # check umounts of each MDT on MDS have reached kthread_stop()
16544                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16545                         error "$i: expected $nb umount"
16546                 wait_update $i \
16547                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16548                         error "$i: umount not found in D-state"
16549         done
16550
16551         # release all GC-threads
16552         do_nodes $mdts $LCTL set_param fail_loc=0
16553
16554         # wait for MDT stop to complete
16555         for i in $(seq $MDSCOUNT); do
16556                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16557         done
16558
16559         # XXX
16560         # may try to check if any orphan changelog records are present
16561         # via ldiskfs/zfs and llog_reader...
16562
16563         # re-start/mount MDTs
16564         for i in $(seq $MDSCOUNT); do
16565                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16566                         error "Fail to start mds$i"
16567         done
16568
16569         local first_rec
16570         for i in $(seq $MDSCOUNT); do
16571                 # check cl_user1 still registered
16572                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16573                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16574                 # check cl_user2 unregistered
16575                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16576                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16577
16578                 # check changelogs are present and starting at $user_rec1 + 1
16579                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16580                 [ -n "$user_rec1" ] ||
16581                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16582                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16583                             awk '{ print $1; exit; }')
16584
16585                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16586                 [ $((user_rec1 + 1)) == $first_rec ] ||
16587                         error "mds$i: first index should be $user_rec1 + 1, " \
16588                               "but is $first_rec"
16589         done
16590 }
16591 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16592               "during mount"
16593
16594 test_160i() {
16595
16596         local mdts=$(comma_list $(mdts_nodes))
16597
16598         changelog_register || error "first changelog_register failed"
16599
16600         # generate some changelog records to accumulate on each MDT
16601         # use all_char because created files should be evenly distributed
16602         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16603                 error "test_mkdir $tdir failed"
16604         for ((i = 0; i < MDSCOUNT; i++)); do
16605                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16606                         error "create $DIR/$tdir/d$i.1 failed"
16607         done
16608
16609         # check changelogs have been generated
16610         local nbcl=$(changelog_dump | wc -l)
16611         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16612
16613         # simulate race between register and unregister
16614         # XXX as fail_loc is set per-MDS, with DNE configs the race
16615         # simulation will only occur for one MDT per MDS and for the
16616         # others the normal race scenario will take place
16617         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16618         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16619         do_nodes $mdts $LCTL set_param fail_val=1
16620
16621         # unregister 1st user
16622         changelog_deregister &
16623         local pid1=$!
16624         # wait some time for deregister work to reach race rdv
16625         sleep 2
16626         # register 2nd user
16627         changelog_register || error "2nd user register failed"
16628
16629         wait $pid1 || error "1st user deregister failed"
16630
16631         local i
16632         local last_rec
16633         declare -A LAST_REC
16634         for i in $(seq $MDSCOUNT); do
16635                 if changelog_users mds$i | grep "^cl"; then
16636                         # make sure new records are added with one user present
16637                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16638                                           awk '/^current.index:/ { print $NF }')
16639                 else
16640                         error "mds$i has no user registered"
16641                 fi
16642         done
16643
16644         # generate more changelog records to accumulate on each MDT
16645         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16646                 error "create $DIR/$tdir/${tfile}bis failed"
16647
16648         for i in $(seq $MDSCOUNT); do
16649                 last_rec=$(changelog_users $SINGLEMDS |
16650                            awk '/^current.index:/ { print $NF }')
16651                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16652                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16653                         error "changelogs are off on mds$i"
16654         done
16655 }
16656 run_test 160i "changelog user register/unregister race"
16657
16658 test_160j() {
16659         remote_mds_nodsh && skip "remote MDS with nodsh"
16660         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16661                 skip "Need MDS version at least 2.12.56"
16662
16663         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16664         stack_trap "umount $MOUNT2" EXIT
16665
16666         changelog_register || error "first changelog_register failed"
16667         stack_trap "changelog_deregister" EXIT
16668
16669         # generate some changelog
16670         # use all_char because created files should be evenly distributed
16671         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16672                 error "mkdir $tdir failed"
16673         for ((i = 0; i < MDSCOUNT; i++)); do
16674                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16675                         error "create $DIR/$tdir/d$i.1 failed"
16676         done
16677
16678         # open the changelog device
16679         exec 3>/dev/changelog-$FSNAME-MDT0000
16680         stack_trap "exec 3>&-" EXIT
16681         exec 4</dev/changelog-$FSNAME-MDT0000
16682         stack_trap "exec 4<&-" EXIT
16683
16684         # umount the first lustre mount
16685         umount $MOUNT
16686         stack_trap "mount_client $MOUNT" EXIT
16687
16688         # read changelog, which may or may not fail, but should not crash
16689         cat <&4 >/dev/null
16690
16691         # clear changelog
16692         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16693         changelog_users $SINGLEMDS | grep -q $cl_user ||
16694                 error "User $cl_user not found in changelog_users"
16695
16696         printf 'clear:'$cl_user':0' >&3
16697 }
16698 run_test 160j "client can be umounted while its chanangelog is being used"
16699
16700 test_160k() {
16701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16702         remote_mds_nodsh && skip "remote MDS with nodsh"
16703
16704         mkdir -p $DIR/$tdir/1/1
16705
16706         changelog_register || error "changelog_register failed"
16707         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16708
16709         changelog_users $SINGLEMDS | grep -q $cl_user ||
16710                 error "User '$cl_user' not found in changelog_users"
16711 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16712         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16713         rmdir $DIR/$tdir/1/1 & sleep 1
16714         mkdir $DIR/$tdir/2
16715         touch $DIR/$tdir/2/2
16716         rm -rf $DIR/$tdir/2
16717
16718         wait
16719         sleep 4
16720
16721         changelog_dump | grep rmdir || error "rmdir not recorded"
16722 }
16723 run_test 160k "Verify that changelog records are not lost"
16724
16725 # Verifies that a file passed as a parameter has recently had an operation
16726 # performed on it that has generated an MTIME changelog which contains the
16727 # correct parent FID. As files might reside on a different MDT from the
16728 # parent directory in DNE configurations, the FIDs are translated to paths
16729 # before being compared, which should be identical
16730 compare_mtime_changelog() {
16731         local file="${1}"
16732         local mdtidx
16733         local mtime
16734         local cl_fid
16735         local pdir
16736         local dir
16737
16738         mdtidx=$($LFS getstripe --mdt-index $file)
16739         mdtidx=$(printf "%04x" $mdtidx)
16740
16741         # Obtain the parent FID from the MTIME changelog
16742         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16743         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16744
16745         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16746         [ -z "$cl_fid" ] && error "parent FID not present"
16747
16748         # Verify that the path for the parent FID is the same as the path for
16749         # the test directory
16750         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16751
16752         dir=$(dirname $1)
16753
16754         [[ "${pdir%/}" == "$dir" ]] ||
16755                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16756 }
16757
16758 test_160l() {
16759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16760
16761         remote_mds_nodsh && skip "remote MDS with nodsh"
16762         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16763                 skip "Need MDS version at least 2.13.55"
16764
16765         local cl_user
16766
16767         changelog_register || error "changelog_register failed"
16768         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16769
16770         changelog_users $SINGLEMDS | grep -q $cl_user ||
16771                 error "User '$cl_user' not found in changelog_users"
16772
16773         # Clear some types so that MTIME changelogs are generated
16774         changelog_chmask "-CREAT"
16775         changelog_chmask "-CLOSE"
16776
16777         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16778
16779         # Test CL_MTIME during setattr
16780         touch $DIR/$tdir/$tfile
16781         compare_mtime_changelog $DIR/$tdir/$tfile
16782
16783         # Test CL_MTIME during close
16784         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16785         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16786 }
16787 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16788
16789 test_160m() {
16790         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16791         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16792                 skip "Need MDS version at least 2.14.51"
16793         local cl_users
16794         local cl_user1
16795         local cl_user2
16796         local pid1
16797
16798         # Create a user
16799         changelog_register || error "first changelog_register failed"
16800         changelog_register || error "second changelog_register failed"
16801
16802         cl_users=(${CL_USERS[mds1]})
16803         cl_user1="${cl_users[0]}"
16804         cl_user2="${cl_users[1]}"
16805         # generate some changelog records to accumulate on MDT0
16806         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16807         createmany -m $DIR/$tdir/$tfile 50 ||
16808                 error "create $DIR/$tdir/$tfile failed"
16809         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16810         rm -f $DIR/$tdir
16811
16812         # check changelogs have been generated
16813         local nbcl=$(changelog_dump | wc -l)
16814         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16815
16816 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16817         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16818
16819         __changelog_clear mds1 $cl_user1 +10
16820         __changelog_clear mds1 $cl_user2 0 &
16821         pid1=$!
16822         sleep 2
16823         __changelog_clear mds1 $cl_user1 0 ||
16824                 error "fail to cancel record for $cl_user1"
16825         wait $pid1
16826         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16827 }
16828 run_test 160m "Changelog clear race"
16829
16830 test_160n() {
16831         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16832         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16833                 skip "Need MDS version at least 2.14.51"
16834         local cl_users
16835         local cl_user1
16836         local cl_user2
16837         local pid1
16838         local first_rec
16839         local last_rec=0
16840
16841         # Create a user
16842         changelog_register || error "first changelog_register failed"
16843
16844         cl_users=(${CL_USERS[mds1]})
16845         cl_user1="${cl_users[0]}"
16846
16847         # generate some changelog records to accumulate on MDT0
16848         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16849         first_rec=$(changelog_users $SINGLEMDS |
16850                         awk '/^current.index:/ { print $NF }')
16851         while (( last_rec < (( first_rec + 65000)) )); do
16852                 createmany -m $DIR/$tdir/$tfile 10000 ||
16853                         error "create $DIR/$tdir/$tfile failed"
16854
16855                 for i in $(seq 0 10000); do
16856                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16857                                 > /dev/null
16858                 done
16859
16860                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16861                         error "unlinkmany failed unlink"
16862                 last_rec=$(changelog_users $SINGLEMDS |
16863                         awk '/^current.index:/ { print $NF }')
16864                 echo last record $last_rec
16865                 (( last_rec == 0 )) && error "no changelog found"
16866         done
16867
16868 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16869         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16870
16871         __changelog_clear mds1 $cl_user1 0 &
16872         pid1=$!
16873         sleep 2
16874         __changelog_clear mds1 $cl_user1 0 ||
16875                 error "fail to cancel record for $cl_user1"
16876         wait $pid1
16877         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16878 }
16879 run_test 160n "Changelog destroy race"
16880
16881 test_160o() {
16882         local mdt="$(facet_svc $SINGLEMDS)"
16883
16884         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16885         remote_mds_nodsh && skip "remote MDS with nodsh"
16886         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16887                 skip "Need MDS version at least 2.14.52"
16888
16889         changelog_register --user test_160o -m unlnk+close+open ||
16890                 error "changelog_register failed"
16891
16892         do_facet $SINGLEMDS $LCTL --device $mdt \
16893                                 changelog_register -u "Tt3_-#" &&
16894                 error "bad symbols in name should fail"
16895
16896         do_facet $SINGLEMDS $LCTL --device $mdt \
16897                                 changelog_register -u test_160o &&
16898                 error "the same name registration should fail"
16899
16900         do_facet $SINGLEMDS $LCTL --device $mdt \
16901                         changelog_register -u test_160toolongname &&
16902                 error "too long name registration should fail"
16903
16904         changelog_chmask "MARK+HSM"
16905         lctl get_param mdd.*.changelog*mask
16906         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16907         changelog_users $SINGLEMDS | grep -q $cl_user ||
16908                 error "User $cl_user not found in changelog_users"
16909         #verify username
16910         echo $cl_user | grep -q test_160o ||
16911                 error "User $cl_user has no specific name 'test160o'"
16912
16913         # change something
16914         changelog_clear 0 || error "changelog_clear failed"
16915         # generate some changelog records to accumulate on MDT0
16916         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16917         touch $DIR/$tdir/$tfile                 # open 1
16918
16919         OPENS=$(changelog_dump | grep -c "OPEN")
16920         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16921
16922         # must be no MKDIR it wasn't set as user mask
16923         MKDIR=$(changelog_dump | grep -c "MKDIR")
16924         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16925
16926         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16927                                 mdd.$mdt.changelog_current_mask -n)
16928         # register maskless user
16929         changelog_register || error "changelog_register failed"
16930         # effective mask should be not changed because it is not minimal
16931         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16932                                 mdd.$mdt.changelog_current_mask -n)
16933         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16934         # set server mask to minimal value
16935         changelog_chmask "MARK"
16936         # check effective mask again, should be treated as DEFMASK now
16937         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16938                                 mdd.$mdt.changelog_current_mask -n)
16939         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16940
16941         do_facet $SINGLEMDS $LCTL --device $mdt \
16942                                 changelog_deregister -u test_160o ||
16943                 error "cannot deregister by name"
16944 }
16945 run_test 160o "changelog user name and mask"
16946
16947 test_160p() {
16948         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16949         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16950                 skip "Need MDS version at least 2.14.51"
16951         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16952         local cl_users
16953         local cl_user1
16954         local entry_count
16955
16956         # Create a user
16957         changelog_register || error "first changelog_register failed"
16958
16959         cl_users=(${CL_USERS[mds1]})
16960         cl_user1="${cl_users[0]}"
16961
16962         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16963         createmany -m $DIR/$tdir/$tfile 50 ||
16964                 error "create $DIR/$tdir/$tfile failed"
16965         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16966         rm -rf $DIR/$tdir
16967
16968         # check changelogs have been generated
16969         entry_count=$(changelog_dump | wc -l)
16970         ((entry_count != 0)) || error "no changelog entries found"
16971
16972         # remove changelog_users and check that orphan entries are removed
16973         stop mds1
16974         local dev=$(mdsdevname 1)
16975         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16976         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16977         entry_count=$(changelog_dump | wc -l)
16978         ((entry_count == 0)) ||
16979                 error "found $entry_count changelog entries, expected none"
16980 }
16981 run_test 160p "Changelog orphan cleanup with no users"
16982
16983 test_160q() {
16984         local mdt="$(facet_svc $SINGLEMDS)"
16985         local clu
16986
16987         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16988         remote_mds_nodsh && skip "remote MDS with nodsh"
16989         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16990                 skip "Need MDS version at least 2.14.54"
16991
16992         # set server mask to minimal value like server init does
16993         changelog_chmask "MARK"
16994         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16995                 error "changelog_register failed"
16996         # check effective mask again, should be treated as DEFMASK now
16997         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16998                                 mdd.$mdt.changelog_current_mask -n)
16999         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17000                 error "changelog_deregister failed"
17001         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17002 }
17003 run_test 160q "changelog effective mask is DEFMASK if not set"
17004
17005 test_160s() {
17006         remote_mds_nodsh && skip "remote MDS with nodsh"
17007         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17008                 skip "Need MDS version at least 2.14.55"
17009
17010         local mdts=$(comma_list $(mdts_nodes))
17011
17012         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17013         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17014                                        fail_val=$((24 * 3600 * 10))
17015
17016         # Create a user which is 10 days old
17017         changelog_register || error "first changelog_register failed"
17018         local cl_users
17019         declare -A cl_user1
17020         local i
17021
17022         # generate some changelog records to accumulate on each MDT
17023         # use all_char because created files should be evenly distributed
17024         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17025                 error "test_mkdir $tdir failed"
17026         for ((i = 0; i < MDSCOUNT; i++)); do
17027                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17028                         error "create $DIR/$tdir/d$i.1 failed"
17029         done
17030
17031         # check changelogs have been generated
17032         local nbcl=$(changelog_dump | wc -l)
17033         (( nbcl > 0 )) || error "no changelogs found"
17034
17035         # reduce the max_idle_indexes value to make sure we exceed it
17036         for param in "changelog_max_idle_indexes=2097446912" \
17037                      "changelog_max_idle_time=2592000" \
17038                      "changelog_gc=1" \
17039                      "changelog_min_gc_interval=2"; do
17040                 local MDT0=$(facet_svc $SINGLEMDS)
17041                 local var="${param%=*}"
17042                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17043
17044                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17045                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17046                         error "unable to set mdd.*.$param"
17047         done
17048
17049         local start=$SECONDS
17050         for i in $(seq $MDSCOUNT); do
17051                 cl_users=(${CL_USERS[mds$i]})
17052                 cl_user1[mds$i]="${cl_users[0]}"
17053
17054                 [[ -n "${cl_user1[mds$i]}" ]] ||
17055                         error "mds$i: no user registered"
17056         done
17057
17058         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17059         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17060
17061         # ensure we are past the previous changelog_min_gc_interval set above
17062         local sleep2=$((start + 2 - SECONDS))
17063         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17064
17065         # Generate one more changelog to trigger GC
17066         for ((i = 0; i < MDSCOUNT; i++)); do
17067                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17068                         error "create $DIR/$tdir/d$i.3 failed"
17069         done
17070
17071         # ensure gc thread is done
17072         for node in $(mdts_nodes); do
17073                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17074                         error "$node: GC-thread not done"
17075         done
17076
17077         do_nodes $mdts $LCTL set_param fail_loc=0
17078
17079         for (( i = 1; i <= MDSCOUNT; i++ )); do
17080                 # check cl_user1 is purged
17081                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17082                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17083         done
17084         return 0
17085 }
17086 run_test 160s "changelog garbage collect on idle records * time"
17087
17088 test_161a() {
17089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17090
17091         test_mkdir -c1 $DIR/$tdir
17092         cp /etc/hosts $DIR/$tdir/$tfile
17093         test_mkdir -c1 $DIR/$tdir/foo1
17094         test_mkdir -c1 $DIR/$tdir/foo2
17095         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17096         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17097         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17098         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17099         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17100         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17101                 $LFS fid2path $DIR $FID
17102                 error "bad link ea"
17103         fi
17104         # middle
17105         rm $DIR/$tdir/foo2/zachary
17106         # last
17107         rm $DIR/$tdir/foo2/thor
17108         # first
17109         rm $DIR/$tdir/$tfile
17110         # rename
17111         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17112         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17113                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17114         rm $DIR/$tdir/foo2/maggie
17115
17116         # overflow the EA
17117         local longname=$tfile.avg_len_is_thirty_two_
17118         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17119                 error_noexit 'failed to unlink many hardlinks'" EXIT
17120         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17121                 error "failed to hardlink many files"
17122         links=$($LFS fid2path $DIR $FID | wc -l)
17123         echo -n "${links}/1000 links in link EA"
17124         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17125 }
17126 run_test 161a "link ea sanity"
17127
17128 test_161b() {
17129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17130         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17131
17132         local MDTIDX=1
17133         local remote_dir=$DIR/$tdir/remote_dir
17134
17135         mkdir -p $DIR/$tdir
17136         $LFS mkdir -i $MDTIDX $remote_dir ||
17137                 error "create remote directory failed"
17138
17139         cp /etc/hosts $remote_dir/$tfile
17140         mkdir -p $remote_dir/foo1
17141         mkdir -p $remote_dir/foo2
17142         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17143         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17144         ln $remote_dir/$tfile $remote_dir/foo1/luna
17145         ln $remote_dir/$tfile $remote_dir/foo2/thor
17146
17147         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17148                      tr -d ']')
17149         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17150                 $LFS fid2path $DIR $FID
17151                 error "bad link ea"
17152         fi
17153         # middle
17154         rm $remote_dir/foo2/zachary
17155         # last
17156         rm $remote_dir/foo2/thor
17157         # first
17158         rm $remote_dir/$tfile
17159         # rename
17160         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17161         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17162         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17163                 $LFS fid2path $DIR $FID
17164                 error "bad link rename"
17165         fi
17166         rm $remote_dir/foo2/maggie
17167
17168         # overflow the EA
17169         local longname=filename_avg_len_is_thirty_two_
17170         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17171                 error "failed to hardlink many files"
17172         links=$($LFS fid2path $DIR $FID | wc -l)
17173         echo -n "${links}/1000 links in link EA"
17174         [[ ${links} -gt 60 ]] ||
17175                 error "expected at least 60 links in link EA"
17176         unlinkmany $remote_dir/foo2/$longname 1000 ||
17177         error "failed to unlink many hardlinks"
17178 }
17179 run_test 161b "link ea sanity under remote directory"
17180
17181 test_161c() {
17182         remote_mds_nodsh && skip "remote MDS with nodsh"
17183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17184         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17185                 skip "Need MDS version at least 2.1.5"
17186
17187         # define CLF_RENAME_LAST 0x0001
17188         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17189         changelog_register || error "changelog_register failed"
17190
17191         rm -rf $DIR/$tdir
17192         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17193         touch $DIR/$tdir/foo_161c
17194         touch $DIR/$tdir/bar_161c
17195         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17196         changelog_dump | grep RENME | tail -n 5
17197         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17198         changelog_clear 0 || error "changelog_clear failed"
17199         if [ x$flags != "x0x1" ]; then
17200                 error "flag $flags is not 0x1"
17201         fi
17202
17203         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17204         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17205         touch $DIR/$tdir/foo_161c
17206         touch $DIR/$tdir/bar_161c
17207         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17208         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17209         changelog_dump | grep RENME | tail -n 5
17210         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17211         changelog_clear 0 || error "changelog_clear failed"
17212         if [ x$flags != "x0x0" ]; then
17213                 error "flag $flags is not 0x0"
17214         fi
17215         echo "rename overwrite a target having nlink > 1," \
17216                 "changelog record has flags of $flags"
17217
17218         # rename doesn't overwrite a target (changelog flag 0x0)
17219         touch $DIR/$tdir/foo_161c
17220         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17221         changelog_dump | grep RENME | tail -n 5
17222         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17223         changelog_clear 0 || error "changelog_clear failed"
17224         if [ x$flags != "x0x0" ]; then
17225                 error "flag $flags is not 0x0"
17226         fi
17227         echo "rename doesn't overwrite a target," \
17228                 "changelog record has flags of $flags"
17229
17230         # define CLF_UNLINK_LAST 0x0001
17231         # unlink a file having nlink = 1 (changelog flag 0x1)
17232         rm -f $DIR/$tdir/foo2_161c
17233         changelog_dump | grep UNLNK | tail -n 5
17234         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17235         changelog_clear 0 || error "changelog_clear failed"
17236         if [ x$flags != "x0x1" ]; then
17237                 error "flag $flags is not 0x1"
17238         fi
17239         echo "unlink a file having nlink = 1," \
17240                 "changelog record has flags of $flags"
17241
17242         # unlink a file having nlink > 1 (changelog flag 0x0)
17243         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17244         rm -f $DIR/$tdir/foobar_161c
17245         changelog_dump | grep UNLNK | tail -n 5
17246         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17247         changelog_clear 0 || error "changelog_clear failed"
17248         if [ x$flags != "x0x0" ]; then
17249                 error "flag $flags is not 0x0"
17250         fi
17251         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17252 }
17253 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17254
17255 test_161d() {
17256         remote_mds_nodsh && skip "remote MDS with nodsh"
17257         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17258
17259         local pid
17260         local fid
17261
17262         changelog_register || error "changelog_register failed"
17263
17264         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17265         # interfer with $MOUNT/.lustre/fid/ access
17266         mkdir $DIR/$tdir
17267         [[ $? -eq 0 ]] || error "mkdir failed"
17268
17269         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17270         $LCTL set_param fail_loc=0x8000140c
17271         # 5s pause
17272         $LCTL set_param fail_val=5
17273
17274         # create file
17275         echo foofoo > $DIR/$tdir/$tfile &
17276         pid=$!
17277
17278         # wait for create to be delayed
17279         sleep 2
17280
17281         ps -p $pid
17282         [[ $? -eq 0 ]] || error "create should be blocked"
17283
17284         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17285         stack_trap "rm -f $tempfile"
17286         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17287         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17288         # some delay may occur during ChangeLog publishing and file read just
17289         # above, that could allow file write to happen finally
17290         [[ -s $tempfile ]] && echo "file should be empty"
17291
17292         $LCTL set_param fail_loc=0
17293
17294         wait $pid
17295         [[ $? -eq 0 ]] || error "create failed"
17296 }
17297 run_test 161d "create with concurrent .lustre/fid access"
17298
17299 check_path() {
17300         local expected="$1"
17301         shift
17302         local fid="$2"
17303
17304         local path
17305         path=$($LFS fid2path "$@")
17306         local rc=$?
17307
17308         if [ $rc -ne 0 ]; then
17309                 error "path looked up of '$expected' failed: rc=$rc"
17310         elif [ "$path" != "$expected" ]; then
17311                 error "path looked up '$path' instead of '$expected'"
17312         else
17313                 echo "FID '$fid' resolves to path '$path' as expected"
17314         fi
17315 }
17316
17317 test_162a() { # was test_162
17318         test_mkdir -p -c1 $DIR/$tdir/d2
17319         touch $DIR/$tdir/d2/$tfile
17320         touch $DIR/$tdir/d2/x1
17321         touch $DIR/$tdir/d2/x2
17322         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17323         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17324         # regular file
17325         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17326         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17327
17328         # softlink
17329         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17330         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17331         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17332
17333         # softlink to wrong file
17334         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17335         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17336         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17337
17338         # hardlink
17339         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17340         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17341         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17342         # fid2path dir/fsname should both work
17343         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17344         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17345
17346         # hardlink count: check that there are 2 links
17347         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17348         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17349
17350         # hardlink indexing: remove the first link
17351         rm $DIR/$tdir/d2/p/q/r/hlink
17352         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17353 }
17354 run_test 162a "path lookup sanity"
17355
17356 test_162b() {
17357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17359
17360         mkdir $DIR/$tdir
17361         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17362                                 error "create striped dir failed"
17363
17364         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17365                                         tail -n 1 | awk '{print $2}')
17366         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17367
17368         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17369         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17370
17371         # regular file
17372         for ((i=0;i<5;i++)); do
17373                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17374                         error "get fid for f$i failed"
17375                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17376
17377                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17378                         error "get fid for d$i failed"
17379                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17380         done
17381
17382         return 0
17383 }
17384 run_test 162b "striped directory path lookup sanity"
17385
17386 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17387 test_162c() {
17388         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17389                 skip "Need MDS version at least 2.7.51"
17390
17391         local lpath=$tdir.local
17392         local rpath=$tdir.remote
17393
17394         test_mkdir $DIR/$lpath
17395         test_mkdir $DIR/$rpath
17396
17397         for ((i = 0; i <= 101; i++)); do
17398                 lpath="$lpath/$i"
17399                 mkdir $DIR/$lpath
17400                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17401                         error "get fid for local directory $DIR/$lpath failed"
17402                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17403
17404                 rpath="$rpath/$i"
17405                 test_mkdir $DIR/$rpath
17406                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17407                         error "get fid for remote directory $DIR/$rpath failed"
17408                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17409         done
17410
17411         return 0
17412 }
17413 run_test 162c "fid2path works with paths 100 or more directories deep"
17414
17415 oalr_event_count() {
17416         local event="${1}"
17417         local trace="${2}"
17418
17419         awk -v name="${FSNAME}-OST0000" \
17420             -v event="${event}" \
17421             '$1 == "TRACE" && $2 == event && $3 == name' \
17422             "${trace}" |
17423         wc -l
17424 }
17425
17426 oalr_expect_event_count() {
17427         local event="${1}"
17428         local trace="${2}"
17429         local expect="${3}"
17430         local count
17431
17432         count=$(oalr_event_count "${event}" "${trace}")
17433         if ((count == expect)); then
17434                 return 0
17435         fi
17436
17437         error_noexit "${event} event count was '${count}', expected ${expect}"
17438         cat "${trace}" >&2
17439         exit 1
17440 }
17441
17442 cleanup_165() {
17443         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17444         stop ost1
17445         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17446 }
17447
17448 setup_165() {
17449         sync # Flush previous IOs so we can count log entries.
17450         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17451         stack_trap cleanup_165 EXIT
17452 }
17453
17454 test_165a() {
17455         local trace="/tmp/${tfile}.trace"
17456         local rc
17457         local count
17458
17459         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17460                 skip "OFD access log unsupported"
17461
17462         setup_165
17463         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17464         sleep 5
17465
17466         do_facet ost1 ofd_access_log_reader --list
17467         stop ost1
17468
17469         do_facet ost1 killall -TERM ofd_access_log_reader
17470         wait
17471         rc=$?
17472
17473         if ((rc != 0)); then
17474                 error "ofd_access_log_reader exited with rc = '${rc}'"
17475         fi
17476
17477         # Parse trace file for discovery events:
17478         oalr_expect_event_count alr_log_add "${trace}" 1
17479         oalr_expect_event_count alr_log_eof "${trace}" 1
17480         oalr_expect_event_count alr_log_free "${trace}" 1
17481 }
17482 run_test 165a "ofd access log discovery"
17483
17484 test_165b() {
17485         local trace="/tmp/${tfile}.trace"
17486         local file="${DIR}/${tfile}"
17487         local pfid1
17488         local pfid2
17489         local -a entry
17490         local rc
17491         local count
17492         local size
17493         local flags
17494
17495         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17496                 skip "OFD access log unsupported"
17497
17498         setup_165
17499         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17500         sleep 5
17501
17502         do_facet ost1 ofd_access_log_reader --list
17503
17504         lfs setstripe -c 1 -i 0 "${file}"
17505         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17506                 error "cannot create '${file}'"
17507
17508         sleep 5
17509         do_facet ost1 killall -TERM ofd_access_log_reader
17510         wait
17511         rc=$?
17512
17513         if ((rc != 0)); then
17514                 error "ofd_access_log_reader exited with rc = '${rc}'"
17515         fi
17516
17517         oalr_expect_event_count alr_log_entry "${trace}" 1
17518
17519         pfid1=$($LFS path2fid "${file}")
17520
17521         # 1     2             3   4    5     6   7    8    9     10
17522         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17523         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17524
17525         echo "entry = '${entry[*]}'" >&2
17526
17527         pfid2=${entry[4]}
17528         if [[ "${pfid1}" != "${pfid2}" ]]; then
17529                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17530         fi
17531
17532         size=${entry[8]}
17533         if ((size != 1048576)); then
17534                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17535         fi
17536
17537         flags=${entry[10]}
17538         if [[ "${flags}" != "w" ]]; then
17539                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17540         fi
17541
17542         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17543         sleep 5
17544
17545         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17546                 error "cannot read '${file}'"
17547         sleep 5
17548
17549         do_facet ost1 killall -TERM ofd_access_log_reader
17550         wait
17551         rc=$?
17552
17553         if ((rc != 0)); then
17554                 error "ofd_access_log_reader exited with rc = '${rc}'"
17555         fi
17556
17557         oalr_expect_event_count alr_log_entry "${trace}" 1
17558
17559         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17560         echo "entry = '${entry[*]}'" >&2
17561
17562         pfid2=${entry[4]}
17563         if [[ "${pfid1}" != "${pfid2}" ]]; then
17564                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17565         fi
17566
17567         size=${entry[8]}
17568         if ((size != 524288)); then
17569                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17570         fi
17571
17572         flags=${entry[10]}
17573         if [[ "${flags}" != "r" ]]; then
17574                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17575         fi
17576 }
17577 run_test 165b "ofd access log entries are produced and consumed"
17578
17579 test_165c() {
17580         local trace="/tmp/${tfile}.trace"
17581         local file="${DIR}/${tdir}/${tfile}"
17582
17583         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17584                 skip "OFD access log unsupported"
17585
17586         test_mkdir "${DIR}/${tdir}"
17587
17588         setup_165
17589         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17590         sleep 5
17591
17592         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17593
17594         # 4096 / 64 = 64. Create twice as many entries.
17595         for ((i = 0; i < 128; i++)); do
17596                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17597                         error "cannot create file"
17598         done
17599
17600         sync
17601
17602         do_facet ost1 killall -TERM ofd_access_log_reader
17603         wait
17604         rc=$?
17605         if ((rc != 0)); then
17606                 error "ofd_access_log_reader exited with rc = '${rc}'"
17607         fi
17608
17609         unlinkmany  "${file}-%d" 128
17610 }
17611 run_test 165c "full ofd access logs do not block IOs"
17612
17613 oal_get_read_count() {
17614         local stats="$1"
17615
17616         # STATS lustre-OST0001 alr_read_count 1
17617
17618         do_facet ost1 cat "${stats}" |
17619         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17620              END { print count; }'
17621 }
17622
17623 oal_expect_read_count() {
17624         local stats="$1"
17625         local count
17626         local expect="$2"
17627
17628         # Ask ofd_access_log_reader to write stats.
17629         do_facet ost1 killall -USR1 ofd_access_log_reader
17630
17631         # Allow some time for things to happen.
17632         sleep 1
17633
17634         count=$(oal_get_read_count "${stats}")
17635         if ((count == expect)); then
17636                 return 0
17637         fi
17638
17639         error_noexit "bad read count, got ${count}, expected ${expect}"
17640         do_facet ost1 cat "${stats}" >&2
17641         exit 1
17642 }
17643
17644 test_165d() {
17645         local stats="/tmp/${tfile}.stats"
17646         local file="${DIR}/${tdir}/${tfile}"
17647         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17648
17649         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17650                 skip "OFD access log unsupported"
17651
17652         test_mkdir "${DIR}/${tdir}"
17653
17654         setup_165
17655         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17656         sleep 5
17657
17658         lfs setstripe -c 1 -i 0 "${file}"
17659
17660         do_facet ost1 lctl set_param "${param}=rw"
17661         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17662                 error "cannot create '${file}'"
17663         oal_expect_read_count "${stats}" 1
17664
17665         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17666                 error "cannot read '${file}'"
17667         oal_expect_read_count "${stats}" 2
17668
17669         do_facet ost1 lctl set_param "${param}=r"
17670         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17671                 error "cannot create '${file}'"
17672         oal_expect_read_count "${stats}" 2
17673
17674         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17675                 error "cannot read '${file}'"
17676         oal_expect_read_count "${stats}" 3
17677
17678         do_facet ost1 lctl set_param "${param}=w"
17679         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17680                 error "cannot create '${file}'"
17681         oal_expect_read_count "${stats}" 4
17682
17683         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17684                 error "cannot read '${file}'"
17685         oal_expect_read_count "${stats}" 4
17686
17687         do_facet ost1 lctl set_param "${param}=0"
17688         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17689                 error "cannot create '${file}'"
17690         oal_expect_read_count "${stats}" 4
17691
17692         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17693                 error "cannot read '${file}'"
17694         oal_expect_read_count "${stats}" 4
17695
17696         do_facet ost1 killall -TERM ofd_access_log_reader
17697         wait
17698         rc=$?
17699         if ((rc != 0)); then
17700                 error "ofd_access_log_reader exited with rc = '${rc}'"
17701         fi
17702 }
17703 run_test 165d "ofd_access_log mask works"
17704
17705 test_165e() {
17706         local stats="/tmp/${tfile}.stats"
17707         local file0="${DIR}/${tdir}-0/${tfile}"
17708         local file1="${DIR}/${tdir}-1/${tfile}"
17709
17710         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17711                 skip "OFD access log unsupported"
17712
17713         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17714
17715         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17716         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17717
17718         lfs setstripe -c 1 -i 0 "${file0}"
17719         lfs setstripe -c 1 -i 0 "${file1}"
17720
17721         setup_165
17722         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17723         sleep 5
17724
17725         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17726                 error "cannot create '${file0}'"
17727         sync
17728         oal_expect_read_count "${stats}" 0
17729
17730         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17731                 error "cannot create '${file1}'"
17732         sync
17733         oal_expect_read_count "${stats}" 1
17734
17735         do_facet ost1 killall -TERM ofd_access_log_reader
17736         wait
17737         rc=$?
17738         if ((rc != 0)); then
17739                 error "ofd_access_log_reader exited with rc = '${rc}'"
17740         fi
17741 }
17742 run_test 165e "ofd_access_log MDT index filter works"
17743
17744 test_165f() {
17745         local trace="/tmp/${tfile}.trace"
17746         local rc
17747         local count
17748
17749         setup_165
17750         do_facet ost1 timeout 60 ofd_access_log_reader \
17751                 --exit-on-close --debug=- --trace=- > "${trace}" &
17752         sleep 5
17753         stop ost1
17754
17755         wait
17756         rc=$?
17757
17758         if ((rc != 0)); then
17759                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17760                 cat "${trace}"
17761                 exit 1
17762         fi
17763 }
17764 run_test 165f "ofd_access_log_reader --exit-on-close works"
17765
17766 test_169() {
17767         # do directio so as not to populate the page cache
17768         log "creating a 10 Mb file"
17769         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17770                 error "multiop failed while creating a file"
17771         log "starting reads"
17772         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17773         log "truncating the file"
17774         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17775                 error "multiop failed while truncating the file"
17776         log "killing dd"
17777         kill %+ || true # reads might have finished
17778         echo "wait until dd is finished"
17779         wait
17780         log "removing the temporary file"
17781         rm -rf $DIR/$tfile || error "tmp file removal failed"
17782 }
17783 run_test 169 "parallel read and truncate should not deadlock"
17784
17785 test_170() {
17786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17787
17788         $LCTL clear     # bug 18514
17789         $LCTL debug_daemon start $TMP/${tfile}_log_good
17790         touch $DIR/$tfile
17791         $LCTL debug_daemon stop
17792         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17793                 error "sed failed to read log_good"
17794
17795         $LCTL debug_daemon start $TMP/${tfile}_log_good
17796         rm -rf $DIR/$tfile
17797         $LCTL debug_daemon stop
17798
17799         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17800                error "lctl df log_bad failed"
17801
17802         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17803         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17804
17805         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17806         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17807
17808         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17809                 error "bad_line good_line1 good_line2 are empty"
17810
17811         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17812         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17813         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17814
17815         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17816         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17817         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17818
17819         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17820                 error "bad_line_new good_line_new are empty"
17821
17822         local expected_good=$((good_line1 + good_line2*2))
17823
17824         rm -f $TMP/${tfile}*
17825         # LU-231, short malformed line may not be counted into bad lines
17826         if [ $bad_line -ne $bad_line_new ] &&
17827                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17828                 error "expected $bad_line bad lines, but got $bad_line_new"
17829                 return 1
17830         fi
17831
17832         if [ $expected_good -ne $good_line_new ]; then
17833                 error "expected $expected_good good lines, but got $good_line_new"
17834                 return 2
17835         fi
17836         true
17837 }
17838 run_test 170 "test lctl df to handle corrupted log ====================="
17839
17840 test_171() { # bug20592
17841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17842
17843         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17844         $LCTL set_param fail_loc=0x50e
17845         $LCTL set_param fail_val=3000
17846         multiop_bg_pause $DIR/$tfile O_s || true
17847         local MULTIPID=$!
17848         kill -USR1 $MULTIPID
17849         # cause log dump
17850         sleep 3
17851         wait $MULTIPID
17852         if dmesg | grep "recursive fault"; then
17853                 error "caught a recursive fault"
17854         fi
17855         $LCTL set_param fail_loc=0
17856         true
17857 }
17858 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17859
17860 test_172() {
17861
17862         #define OBD_FAIL_OBD_CLEANUP  0x60e
17863         $LCTL set_param fail_loc=0x60e
17864         umount $MOUNT || error "umount $MOUNT failed"
17865         stack_trap "mount_client $MOUNT"
17866
17867         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
17868                 error "no client OBDs are remained"
17869
17870         $LCTL dl | while read devno state type name foo; do
17871                 case $type in
17872                 lov|osc|lmv|mdc)
17873                         $LCTL --device $name cleanup
17874                         $LCTL --device $name detach
17875                         ;;
17876                 *)
17877                         # skip server devices
17878                         ;;
17879                 esac
17880         done
17881
17882         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
17883                 $LCTL dl | egrep " osc | lov | lmv | mdc "
17884                 error "some client OBDs are still remained"
17885         fi
17886
17887 }
17888 run_test 172 "manual device removal with lctl cleanup/detach ======"
17889
17890 # it would be good to share it with obdfilter-survey/iokit-libecho code
17891 setup_obdecho_osc () {
17892         local rc=0
17893         local ost_nid=$1
17894         local obdfilter_name=$2
17895         echo "Creating new osc for $obdfilter_name on $ost_nid"
17896         # make sure we can find loopback nid
17897         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17898
17899         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17900                            ${obdfilter_name}_osc_UUID || rc=2; }
17901         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17902                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17903         return $rc
17904 }
17905
17906 cleanup_obdecho_osc () {
17907         local obdfilter_name=$1
17908         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17909         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17910         return 0
17911 }
17912
17913 obdecho_test() {
17914         local OBD=$1
17915         local node=$2
17916         local pages=${3:-64}
17917         local rc=0
17918         local id
17919
17920         local count=10
17921         local obd_size=$(get_obd_size $node $OBD)
17922         local page_size=$(get_page_size $node)
17923         if [[ -n "$obd_size" ]]; then
17924                 local new_count=$((obd_size / (pages * page_size / 1024)))
17925                 [[ $new_count -ge $count ]] || count=$new_count
17926         fi
17927
17928         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17929         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17930                            rc=2; }
17931         if [ $rc -eq 0 ]; then
17932             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17933             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17934         fi
17935         echo "New object id is $id"
17936         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17937                            rc=4; }
17938         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17939                            "test_brw $count w v $pages $id" || rc=4; }
17940         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17941                            rc=4; }
17942         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17943                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17944         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17945                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17946         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17947         return $rc
17948 }
17949
17950 test_180a() {
17951         skip "obdecho on osc is no longer supported"
17952 }
17953 run_test 180a "test obdecho on osc"
17954
17955 test_180b() {
17956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17957         remote_ost_nodsh && skip "remote OST with nodsh"
17958
17959         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17960                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17961                 error "failed to load module obdecho"
17962
17963         local target=$(do_facet ost1 $LCTL dl |
17964                        awk '/obdfilter/ { print $4; exit; }')
17965
17966         if [ -n "$target" ]; then
17967                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17968         else
17969                 do_facet ost1 $LCTL dl
17970                 error "there is no obdfilter target on ost1"
17971         fi
17972 }
17973 run_test 180b "test obdecho directly on obdfilter"
17974
17975 test_180c() { # LU-2598
17976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17977         remote_ost_nodsh && skip "remote OST with nodsh"
17978         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17979                 skip "Need MDS version at least 2.4.0"
17980
17981         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17982                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17983                 error "failed to load module obdecho"
17984
17985         local target=$(do_facet ost1 $LCTL dl |
17986                        awk '/obdfilter/ { print $4; exit; }')
17987
17988         if [ -n "$target" ]; then
17989                 local pages=16384 # 64MB bulk I/O RPC size
17990
17991                 obdecho_test "$target" ost1 "$pages" ||
17992                         error "obdecho_test with pages=$pages failed with $?"
17993         else
17994                 do_facet ost1 $LCTL dl
17995                 error "there is no obdfilter target on ost1"
17996         fi
17997 }
17998 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17999
18000 test_181() { # bug 22177
18001         test_mkdir $DIR/$tdir
18002         # create enough files to index the directory
18003         createmany -o $DIR/$tdir/foobar 4000
18004         # print attributes for debug purpose
18005         lsattr -d .
18006         # open dir
18007         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18008         MULTIPID=$!
18009         # remove the files & current working dir
18010         unlinkmany $DIR/$tdir/foobar 4000
18011         rmdir $DIR/$tdir
18012         kill -USR1 $MULTIPID
18013         wait $MULTIPID
18014         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18015         return 0
18016 }
18017 run_test 181 "Test open-unlinked dir ========================"
18018
18019 test_182a() {
18020         local fcount=1000
18021         local tcount=10
18022
18023         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18024
18025         $LCTL set_param mdc.*.rpc_stats=clear
18026
18027         for (( i = 0; i < $tcount; i++ )) ; do
18028                 mkdir $DIR/$tdir/$i
18029         done
18030
18031         for (( i = 0; i < $tcount; i++ )) ; do
18032                 createmany -o $DIR/$tdir/$i/f- $fcount &
18033         done
18034         wait
18035
18036         for (( i = 0; i < $tcount; i++ )) ; do
18037                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18038         done
18039         wait
18040
18041         $LCTL get_param mdc.*.rpc_stats
18042
18043         rm -rf $DIR/$tdir
18044 }
18045 run_test 182a "Test parallel modify metadata operations from mdc"
18046
18047 test_182b() {
18048         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18049         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18050         local dcount=1000
18051         local tcount=10
18052         local stime
18053         local etime
18054         local delta
18055
18056         do_facet mds1 $LCTL list_param \
18057                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18058                 skip "MDS lacks parallel RPC handling"
18059
18060         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18061
18062         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18063                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18064
18065         stime=$(date +%s)
18066         createmany -i 0 -d $DIR/$tdir/t- $tcount
18067
18068         for (( i = 0; i < $tcount; i++ )) ; do
18069                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18070         done
18071         wait
18072         etime=$(date +%s)
18073         delta=$((etime - stime))
18074         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18075
18076         stime=$(date +%s)
18077         for (( i = 0; i < $tcount; i++ )) ; do
18078                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18079         done
18080         wait
18081         etime=$(date +%s)
18082         delta=$((etime - stime))
18083         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18084
18085         rm -rf $DIR/$tdir
18086
18087         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18088
18089         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18090
18091         stime=$(date +%s)
18092         createmany -i 0 -d $DIR/$tdir/t- $tcount
18093
18094         for (( i = 0; i < $tcount; i++ )) ; do
18095                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18096         done
18097         wait
18098         etime=$(date +%s)
18099         delta=$((etime - stime))
18100         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18101
18102         stime=$(date +%s)
18103         for (( i = 0; i < $tcount; i++ )) ; do
18104                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18105         done
18106         wait
18107         etime=$(date +%s)
18108         delta=$((etime - stime))
18109         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18110
18111         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18112 }
18113 run_test 182b "Test parallel modify metadata operations from osp"
18114
18115 test_183() { # LU-2275
18116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18117         remote_mds_nodsh && skip "remote MDS with nodsh"
18118         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18119                 skip "Need MDS version at least 2.3.56"
18120
18121         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18122         echo aaa > $DIR/$tdir/$tfile
18123
18124 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18125         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18126
18127         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18128         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18129
18130         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18131
18132         # Flush negative dentry cache
18133         touch $DIR/$tdir/$tfile
18134
18135         # We are not checking for any leaked references here, they'll
18136         # become evident next time we do cleanup with module unload.
18137         rm -rf $DIR/$tdir
18138 }
18139 run_test 183 "No crash or request leak in case of strange dispositions ========"
18140
18141 # test suite 184 is for LU-2016, LU-2017
18142 test_184a() {
18143         check_swap_layouts_support
18144
18145         dir0=$DIR/$tdir/$testnum
18146         test_mkdir -p -c1 $dir0
18147         ref1=/etc/passwd
18148         ref2=/etc/group
18149         file1=$dir0/f1
18150         file2=$dir0/f2
18151         $LFS setstripe -c1 $file1
18152         cp $ref1 $file1
18153         $LFS setstripe -c2 $file2
18154         cp $ref2 $file2
18155         gen1=$($LFS getstripe -g $file1)
18156         gen2=$($LFS getstripe -g $file2)
18157
18158         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18159         gen=$($LFS getstripe -g $file1)
18160         [[ $gen1 != $gen ]] ||
18161                 error "Layout generation on $file1 does not change"
18162         gen=$($LFS getstripe -g $file2)
18163         [[ $gen2 != $gen ]] ||
18164                 error "Layout generation on $file2 does not change"
18165
18166         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18167         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18168
18169         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18170 }
18171 run_test 184a "Basic layout swap"
18172
18173 test_184b() {
18174         check_swap_layouts_support
18175
18176         dir0=$DIR/$tdir/$testnum
18177         mkdir -p $dir0 || error "creating dir $dir0"
18178         file1=$dir0/f1
18179         file2=$dir0/f2
18180         file3=$dir0/f3
18181         dir1=$dir0/d1
18182         dir2=$dir0/d2
18183         mkdir $dir1 $dir2
18184         $LFS setstripe -c1 $file1
18185         $LFS setstripe -c2 $file2
18186         $LFS setstripe -c1 $file3
18187         chown $RUNAS_ID $file3
18188         gen1=$($LFS getstripe -g $file1)
18189         gen2=$($LFS getstripe -g $file2)
18190
18191         $LFS swap_layouts $dir1 $dir2 &&
18192                 error "swap of directories layouts should fail"
18193         $LFS swap_layouts $dir1 $file1 &&
18194                 error "swap of directory and file layouts should fail"
18195         $RUNAS $LFS swap_layouts $file1 $file2 &&
18196                 error "swap of file we cannot write should fail"
18197         $LFS swap_layouts $file1 $file3 &&
18198                 error "swap of file with different owner should fail"
18199         /bin/true # to clear error code
18200 }
18201 run_test 184b "Forbidden layout swap (will generate errors)"
18202
18203 test_184c() {
18204         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18205         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18206         check_swap_layouts_support
18207         check_swap_layout_no_dom $DIR
18208
18209         local dir0=$DIR/$tdir/$testnum
18210         mkdir -p $dir0 || error "creating dir $dir0"
18211
18212         local ref1=$dir0/ref1
18213         local ref2=$dir0/ref2
18214         local file1=$dir0/file1
18215         local file2=$dir0/file2
18216         # create a file large enough for the concurrent test
18217         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18218         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18219         echo "ref file size: ref1($(stat -c %s $ref1))," \
18220              "ref2($(stat -c %s $ref2))"
18221
18222         cp $ref2 $file2
18223         dd if=$ref1 of=$file1 bs=16k &
18224         local DD_PID=$!
18225
18226         # Make sure dd starts to copy file, but wait at most 5 seconds
18227         local loops=0
18228         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18229
18230         $LFS swap_layouts $file1 $file2
18231         local rc=$?
18232         wait $DD_PID
18233         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18234         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18235
18236         # how many bytes copied before swapping layout
18237         local copied=$(stat -c %s $file2)
18238         local remaining=$(stat -c %s $ref1)
18239         remaining=$((remaining - copied))
18240         echo "Copied $copied bytes before swapping layout..."
18241
18242         cmp -n $copied $file1 $ref2 | grep differ &&
18243                 error "Content mismatch [0, $copied) of ref2 and file1"
18244         cmp -n $copied $file2 $ref1 ||
18245                 error "Content mismatch [0, $copied) of ref1 and file2"
18246         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18247                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18248
18249         # clean up
18250         rm -f $ref1 $ref2 $file1 $file2
18251 }
18252 run_test 184c "Concurrent write and layout swap"
18253
18254 test_184d() {
18255         check_swap_layouts_support
18256         check_swap_layout_no_dom $DIR
18257         [ -z "$(which getfattr 2>/dev/null)" ] &&
18258                 skip_env "no getfattr command"
18259
18260         local file1=$DIR/$tdir/$tfile-1
18261         local file2=$DIR/$tdir/$tfile-2
18262         local file3=$DIR/$tdir/$tfile-3
18263         local lovea1
18264         local lovea2
18265
18266         mkdir -p $DIR/$tdir
18267         touch $file1 || error "create $file1 failed"
18268         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18269                 error "create $file2 failed"
18270         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18271                 error "create $file3 failed"
18272         lovea1=$(get_layout_param $file1)
18273
18274         $LFS swap_layouts $file2 $file3 ||
18275                 error "swap $file2 $file3 layouts failed"
18276         $LFS swap_layouts $file1 $file2 ||
18277                 error "swap $file1 $file2 layouts failed"
18278
18279         lovea2=$(get_layout_param $file2)
18280         echo "$lovea1"
18281         echo "$lovea2"
18282         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18283
18284         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18285         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18286 }
18287 run_test 184d "allow stripeless layouts swap"
18288
18289 test_184e() {
18290         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18291                 skip "Need MDS version at least 2.6.94"
18292         check_swap_layouts_support
18293         check_swap_layout_no_dom $DIR
18294         [ -z "$(which getfattr 2>/dev/null)" ] &&
18295                 skip_env "no getfattr command"
18296
18297         local file1=$DIR/$tdir/$tfile-1
18298         local file2=$DIR/$tdir/$tfile-2
18299         local file3=$DIR/$tdir/$tfile-3
18300         local lovea
18301
18302         mkdir -p $DIR/$tdir
18303         touch $file1 || error "create $file1 failed"
18304         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18305                 error "create $file2 failed"
18306         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18307                 error "create $file3 failed"
18308
18309         $LFS swap_layouts $file1 $file2 ||
18310                 error "swap $file1 $file2 layouts failed"
18311
18312         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18313         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18314
18315         echo 123 > $file1 || error "Should be able to write into $file1"
18316
18317         $LFS swap_layouts $file1 $file3 ||
18318                 error "swap $file1 $file3 layouts failed"
18319
18320         echo 123 > $file1 || error "Should be able to write into $file1"
18321
18322         rm -rf $file1 $file2 $file3
18323 }
18324 run_test 184e "Recreate layout after stripeless layout swaps"
18325
18326 test_184f() {
18327         # Create a file with name longer than sizeof(struct stat) ==
18328         # 144 to see if we can get chars from the file name to appear
18329         # in the returned striping. Note that 'f' == 0x66.
18330         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18331
18332         mkdir -p $DIR/$tdir
18333         mcreate $DIR/$tdir/$file
18334         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18335                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18336         fi
18337 }
18338 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18339
18340 test_185() { # LU-2441
18341         # LU-3553 - no volatile file support in old servers
18342         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18343                 skip "Need MDS version at least 2.3.60"
18344
18345         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18346         touch $DIR/$tdir/spoo
18347         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18348         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18349                 error "cannot create/write a volatile file"
18350         [ "$FILESET" == "" ] &&
18351         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18352                 error "FID is still valid after close"
18353
18354         multiop_bg_pause $DIR/$tdir vVw4096_c
18355         local multi_pid=$!
18356
18357         local OLD_IFS=$IFS
18358         IFS=":"
18359         local fidv=($fid)
18360         IFS=$OLD_IFS
18361         # assume that the next FID for this client is sequential, since stdout
18362         # is unfortunately eaten by multiop_bg_pause
18363         local n=$((${fidv[1]} + 1))
18364         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18365         if [ "$FILESET" == "" ]; then
18366                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18367                         error "FID is missing before close"
18368         fi
18369         kill -USR1 $multi_pid
18370         # 1 second delay, so if mtime change we will see it
18371         sleep 1
18372         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18373         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18374 }
18375 run_test 185 "Volatile file support"
18376
18377 function create_check_volatile() {
18378         local idx=$1
18379         local tgt
18380
18381         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18382         local PID=$!
18383         sleep 1
18384         local FID=$(cat /tmp/${tfile}.fid)
18385         [ "$FID" == "" ] && error "can't get FID for volatile"
18386         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18387         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18388         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18389         kill -USR1 $PID
18390         wait
18391         sleep 1
18392         cancel_lru_locks mdc # flush opencache
18393         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18394         return 0
18395 }
18396
18397 test_185a(){
18398         # LU-12516 - volatile creation via .lustre
18399         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18400                 skip "Need MDS version at least 2.3.55"
18401
18402         create_check_volatile 0
18403         [ $MDSCOUNT -lt 2 ] && return 0
18404
18405         # DNE case
18406         create_check_volatile 1
18407
18408         return 0
18409 }
18410 run_test 185a "Volatile file creation in .lustre/fid/"
18411
18412 test_187a() {
18413         remote_mds_nodsh && skip "remote MDS with nodsh"
18414         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18415                 skip "Need MDS version at least 2.3.0"
18416
18417         local dir0=$DIR/$tdir/$testnum
18418         mkdir -p $dir0 || error "creating dir $dir0"
18419
18420         local file=$dir0/file1
18421         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18422         local dv1=$($LFS data_version $file)
18423         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18424         local dv2=$($LFS data_version $file)
18425         [[ $dv1 != $dv2 ]] ||
18426                 error "data version did not change on write $dv1 == $dv2"
18427
18428         # clean up
18429         rm -f $file1
18430 }
18431 run_test 187a "Test data version change"
18432
18433 test_187b() {
18434         remote_mds_nodsh && skip "remote MDS with nodsh"
18435         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18436                 skip "Need MDS version at least 2.3.0"
18437
18438         local dir0=$DIR/$tdir/$testnum
18439         mkdir -p $dir0 || error "creating dir $dir0"
18440
18441         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18442         [[ ${DV[0]} != ${DV[1]} ]] ||
18443                 error "data version did not change on write"\
18444                       " ${DV[0]} == ${DV[1]}"
18445
18446         # clean up
18447         rm -f $file1
18448 }
18449 run_test 187b "Test data version change on volatile file"
18450
18451 test_200() {
18452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18453         remote_mgs_nodsh && skip "remote MGS with nodsh"
18454         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18455
18456         local POOL=${POOL:-cea1}
18457         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18458         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18459         # Pool OST targets
18460         local first_ost=0
18461         local last_ost=$(($OSTCOUNT - 1))
18462         local ost_step=2
18463         local ost_list=$(seq $first_ost $ost_step $last_ost)
18464         local ost_range="$first_ost $last_ost $ost_step"
18465         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18466         local file_dir=$POOL_ROOT/file_tst
18467         local subdir=$test_path/subdir
18468         local rc=0
18469
18470         while : ; do
18471                 # former test_200a test_200b
18472                 pool_add $POOL                          || { rc=$? ; break; }
18473                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18474                 # former test_200c test_200d
18475                 mkdir -p $test_path
18476                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18477                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18478                 mkdir -p $subdir
18479                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18480                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18481                                                         || { rc=$? ; break; }
18482                 # former test_200e test_200f
18483                 local files=$((OSTCOUNT*3))
18484                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18485                                                         || { rc=$? ; break; }
18486                 pool_create_files $POOL $file_dir $files "$ost_list" \
18487                                                         || { rc=$? ; break; }
18488                 # former test_200g test_200h
18489                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18490                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18491
18492                 # former test_201a test_201b test_201c
18493                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18494
18495                 local f=$test_path/$tfile
18496                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18497                 pool_remove $POOL $f                    || { rc=$? ; break; }
18498                 break
18499         done
18500
18501         destroy_test_pools
18502
18503         return $rc
18504 }
18505 run_test 200 "OST pools"
18506
18507 # usage: default_attr <count | size | offset>
18508 default_attr() {
18509         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18510 }
18511
18512 # usage: check_default_stripe_attr
18513 check_default_stripe_attr() {
18514         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18515         case $1 in
18516         --stripe-count|-c)
18517                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18518         --stripe-size|-S)
18519                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18520         --stripe-index|-i)
18521                 EXPECTED=-1;;
18522         *)
18523                 error "unknown getstripe attr '$1'"
18524         esac
18525
18526         [ $ACTUAL == $EXPECTED ] ||
18527                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18528 }
18529
18530 test_204a() {
18531         test_mkdir $DIR/$tdir
18532         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18533
18534         check_default_stripe_attr --stripe-count
18535         check_default_stripe_attr --stripe-size
18536         check_default_stripe_attr --stripe-index
18537 }
18538 run_test 204a "Print default stripe attributes"
18539
18540 test_204b() {
18541         test_mkdir $DIR/$tdir
18542         $LFS setstripe --stripe-count 1 $DIR/$tdir
18543
18544         check_default_stripe_attr --stripe-size
18545         check_default_stripe_attr --stripe-index
18546 }
18547 run_test 204b "Print default stripe size and offset"
18548
18549 test_204c() {
18550         test_mkdir $DIR/$tdir
18551         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18552
18553         check_default_stripe_attr --stripe-count
18554         check_default_stripe_attr --stripe-index
18555 }
18556 run_test 204c "Print default stripe count and offset"
18557
18558 test_204d() {
18559         test_mkdir $DIR/$tdir
18560         $LFS setstripe --stripe-index 0 $DIR/$tdir
18561
18562         check_default_stripe_attr --stripe-count
18563         check_default_stripe_attr --stripe-size
18564 }
18565 run_test 204d "Print default stripe count and size"
18566
18567 test_204e() {
18568         test_mkdir $DIR/$tdir
18569         $LFS setstripe -d $DIR/$tdir
18570
18571         check_default_stripe_attr --stripe-count --raw
18572         check_default_stripe_attr --stripe-size --raw
18573         check_default_stripe_attr --stripe-index --raw
18574 }
18575 run_test 204e "Print raw stripe attributes"
18576
18577 test_204f() {
18578         test_mkdir $DIR/$tdir
18579         $LFS setstripe --stripe-count 1 $DIR/$tdir
18580
18581         check_default_stripe_attr --stripe-size --raw
18582         check_default_stripe_attr --stripe-index --raw
18583 }
18584 run_test 204f "Print raw stripe size and offset"
18585
18586 test_204g() {
18587         test_mkdir $DIR/$tdir
18588         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18589
18590         check_default_stripe_attr --stripe-count --raw
18591         check_default_stripe_attr --stripe-index --raw
18592 }
18593 run_test 204g "Print raw stripe count and offset"
18594
18595 test_204h() {
18596         test_mkdir $DIR/$tdir
18597         $LFS setstripe --stripe-index 0 $DIR/$tdir
18598
18599         check_default_stripe_attr --stripe-count --raw
18600         check_default_stripe_attr --stripe-size --raw
18601 }
18602 run_test 204h "Print raw stripe count and size"
18603
18604 # Figure out which job scheduler is being used, if any,
18605 # or use a fake one
18606 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18607         JOBENV=SLURM_JOB_ID
18608 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18609         JOBENV=LSB_JOBID
18610 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18611         JOBENV=PBS_JOBID
18612 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18613         JOBENV=LOADL_STEP_ID
18614 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18615         JOBENV=JOB_ID
18616 else
18617         $LCTL list_param jobid_name > /dev/null 2>&1
18618         if [ $? -eq 0 ]; then
18619                 JOBENV=nodelocal
18620         else
18621                 JOBENV=FAKE_JOBID
18622         fi
18623 fi
18624 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18625
18626 verify_jobstats() {
18627         local cmd=($1)
18628         shift
18629         local facets="$@"
18630
18631 # we don't really need to clear the stats for this test to work, since each
18632 # command has a unique jobid, but it makes debugging easier if needed.
18633 #       for facet in $facets; do
18634 #               local dev=$(convert_facet2label $facet)
18635 #               # clear old jobstats
18636 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18637 #       done
18638
18639         # use a new JobID for each test, or we might see an old one
18640         [ "$JOBENV" = "FAKE_JOBID" ] &&
18641                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18642
18643         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18644
18645         [ "$JOBENV" = "nodelocal" ] && {
18646                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18647                 $LCTL set_param jobid_name=$FAKE_JOBID
18648                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18649         }
18650
18651         log "Test: ${cmd[*]}"
18652         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18653
18654         if [ $JOBENV = "FAKE_JOBID" ]; then
18655                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18656         else
18657                 ${cmd[*]}
18658         fi
18659
18660         # all files are created on OST0000
18661         for facet in $facets; do
18662                 local stats="*.$(convert_facet2label $facet).job_stats"
18663
18664                 # strip out libtool wrappers for in-tree executables
18665                 if (( $(do_facet $facet lctl get_param $stats |
18666                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18667                         do_facet $facet lctl get_param $stats
18668                         error "No jobstats for $JOBVAL found on $facet::$stats"
18669                 fi
18670         done
18671 }
18672
18673 jobstats_set() {
18674         local new_jobenv=$1
18675
18676         set_persistent_param_and_check client "jobid_var" \
18677                 "$FSNAME.sys.jobid_var" $new_jobenv
18678 }
18679
18680 test_205a() { # Job stats
18681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18682         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18683                 skip "Need MDS version with at least 2.7.1"
18684         remote_mgs_nodsh && skip "remote MGS with nodsh"
18685         remote_mds_nodsh && skip "remote MDS with nodsh"
18686         remote_ost_nodsh && skip "remote OST with nodsh"
18687         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18688                 skip "Server doesn't support jobstats"
18689         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18690
18691         local old_jobenv=$($LCTL get_param -n jobid_var)
18692         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18693
18694         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18695                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18696         else
18697                 stack_trap "do_facet mgs $PERM_CMD \
18698                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18699         fi
18700         changelog_register
18701
18702         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18703                                 mdt.*.job_cleanup_interval | head -n 1)
18704         local new_interval=5
18705         do_facet $SINGLEMDS \
18706                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18707         stack_trap "do_facet $SINGLEMDS \
18708                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18709         local start=$SECONDS
18710
18711         local cmd
18712         # mkdir
18713         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18714         verify_jobstats "$cmd" "$SINGLEMDS"
18715         # rmdir
18716         cmd="rmdir $DIR/$tdir"
18717         verify_jobstats "$cmd" "$SINGLEMDS"
18718         # mkdir on secondary MDT
18719         if [ $MDSCOUNT -gt 1 ]; then
18720                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18721                 verify_jobstats "$cmd" "mds2"
18722         fi
18723         # mknod
18724         cmd="mknod $DIR/$tfile c 1 3"
18725         verify_jobstats "$cmd" "$SINGLEMDS"
18726         # unlink
18727         cmd="rm -f $DIR/$tfile"
18728         verify_jobstats "$cmd" "$SINGLEMDS"
18729         # create all files on OST0000 so verify_jobstats can find OST stats
18730         # open & close
18731         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18732         verify_jobstats "$cmd" "$SINGLEMDS"
18733         # setattr
18734         cmd="touch $DIR/$tfile"
18735         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18736         # write
18737         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18738         verify_jobstats "$cmd" "ost1"
18739         # read
18740         cancel_lru_locks osc
18741         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18742         verify_jobstats "$cmd" "ost1"
18743         # truncate
18744         cmd="$TRUNCATE $DIR/$tfile 0"
18745         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18746         # rename
18747         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18748         verify_jobstats "$cmd" "$SINGLEMDS"
18749         # jobstats expiry - sleep until old stats should be expired
18750         local left=$((new_interval + 5 - (SECONDS - start)))
18751         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18752                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18753                         "0" $left
18754         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18755         verify_jobstats "$cmd" "$SINGLEMDS"
18756         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18757             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18758
18759         # Ensure that jobid are present in changelog (if supported by MDS)
18760         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18761                 changelog_dump | tail -10
18762                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18763                 [ $jobids -eq 9 ] ||
18764                         error "Wrong changelog jobid count $jobids != 9"
18765
18766                 # LU-5862
18767                 JOBENV="disable"
18768                 jobstats_set $JOBENV
18769                 touch $DIR/$tfile
18770                 changelog_dump | grep $tfile
18771                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18772                 [ $jobids -eq 0 ] ||
18773                         error "Unexpected jobids when jobid_var=$JOBENV"
18774         fi
18775
18776         # test '%j' access to environment variable - if supported
18777         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18778                 JOBENV="JOBCOMPLEX"
18779                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18780
18781                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18782         fi
18783
18784         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18785                 JOBENV="JOBCOMPLEX"
18786                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18787
18788                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18789         fi
18790
18791         # test '%j' access to per-session jobid - if supported
18792         if lctl list_param jobid_this_session > /dev/null 2>&1
18793         then
18794                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18795                 lctl set_param jobid_this_session=$USER
18796
18797                 JOBENV="JOBCOMPLEX"
18798                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18799
18800                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18801         fi
18802 }
18803 run_test 205a "Verify job stats"
18804
18805 # LU-13117, LU-13597
18806 test_205b() {
18807         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18808                 skip "Need MDS version at least 2.13.54.91"
18809
18810         local job_stats="mdt.*.job_stats"
18811         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
18812
18813         do_facet mds1 $LCTL set_param $job_stats=clear
18814
18815         # Setting jobid_var to USER might not be supported
18816         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
18817         $LCTL set_param jobid_var=USER || true
18818         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
18819         $LCTL set_param jobid_name="%j.%e.%u"
18820
18821         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18822         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
18823                 { do_facet mds1 $LCTL get_param $job_stats;
18824                   error "Unexpected jobid found"; }
18825         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
18826                 { do_facet mds1 $LCTL get_param $job_stats;
18827                   error "wrong job_stats format found"; }
18828
18829         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
18830                 echo "MDS does not yet escape jobid" && return 0
18831         $LCTL set_param jobid_var=TEST205b
18832         env -i TEST205b="has sp" touch $DIR/$tfile.2
18833         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
18834                 { do_facet mds1 $LCTL get_param $job_stats;
18835                   error "jobid not escaped"; }
18836 }
18837 run_test 205b "Verify job stats jobid and output format"
18838
18839 # LU-13733
18840 test_205c() {
18841         $LCTL set_param llite.*.stats=0
18842         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18843         $LCTL get_param llite.*.stats
18844         $LCTL get_param llite.*.stats | grep \
18845                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18846                         error "wrong client stats format found"
18847 }
18848 run_test 205c "Verify client stats format"
18849
18850 # LU-1480, LU-1773 and LU-1657
18851 test_206() {
18852         mkdir -p $DIR/$tdir
18853         $LFS setstripe -c -1 $DIR/$tdir
18854 #define OBD_FAIL_LOV_INIT 0x1403
18855         $LCTL set_param fail_loc=0xa0001403
18856         $LCTL set_param fail_val=1
18857         touch $DIR/$tdir/$tfile || true
18858 }
18859 run_test 206 "fail lov_init_raid0() doesn't lbug"
18860
18861 test_207a() {
18862         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18863         local fsz=`stat -c %s $DIR/$tfile`
18864         cancel_lru_locks mdc
18865
18866         # do not return layout in getattr intent
18867 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18868         $LCTL set_param fail_loc=0x170
18869         local sz=`stat -c %s $DIR/$tfile`
18870
18871         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18872
18873         rm -rf $DIR/$tfile
18874 }
18875 run_test 207a "can refresh layout at glimpse"
18876
18877 test_207b() {
18878         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18879         local cksum=`md5sum $DIR/$tfile`
18880         local fsz=`stat -c %s $DIR/$tfile`
18881         cancel_lru_locks mdc
18882         cancel_lru_locks osc
18883
18884         # do not return layout in getattr intent
18885 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18886         $LCTL set_param fail_loc=0x171
18887
18888         # it will refresh layout after the file is opened but before read issues
18889         echo checksum is "$cksum"
18890         echo "$cksum" |md5sum -c --quiet || error "file differs"
18891
18892         rm -rf $DIR/$tfile
18893 }
18894 run_test 207b "can refresh layout at open"
18895
18896 test_208() {
18897         # FIXME: in this test suite, only RD lease is used. This is okay
18898         # for now as only exclusive open is supported. After generic lease
18899         # is done, this test suite should be revised. - Jinshan
18900
18901         remote_mds_nodsh && skip "remote MDS with nodsh"
18902         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18903                 skip "Need MDS version at least 2.4.52"
18904
18905         echo "==== test 1: verify get lease work"
18906         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18907
18908         echo "==== test 2: verify lease can be broken by upcoming open"
18909         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18910         local PID=$!
18911         sleep 2
18912
18913         $MULTIOP $DIR/$tfile oO_RDWR:c
18914         kill -USR1 $PID && wait $PID || error "break lease error"
18915
18916         echo "==== test 3: verify lease can't be granted if an open already exists"
18917         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18918         local PID=$!
18919         sleep 2
18920
18921         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18922         kill -USR1 $PID && wait $PID || error "open file error"
18923
18924         echo "==== test 4: lease can sustain over recovery"
18925         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18926         PID=$!
18927         sleep 2
18928
18929         fail mds1
18930
18931         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18932
18933         echo "==== test 5: lease broken can't be regained by replay"
18934         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18935         PID=$!
18936         sleep 2
18937
18938         # open file to break lease and then recovery
18939         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18940         fail mds1
18941
18942         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18943
18944         rm -f $DIR/$tfile
18945 }
18946 run_test 208 "Exclusive open"
18947
18948 test_209() {
18949         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18950                 skip_env "must have disp_stripe"
18951
18952         touch $DIR/$tfile
18953         sync; sleep 5; sync;
18954
18955         echo 3 > /proc/sys/vm/drop_caches
18956         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18957                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18958         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18959
18960         # open/close 500 times
18961         for i in $(seq 500); do
18962                 cat $DIR/$tfile
18963         done
18964
18965         echo 3 > /proc/sys/vm/drop_caches
18966         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18967                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18968         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18969
18970         echo "before: $req_before, after: $req_after"
18971         [ $((req_after - req_before)) -ge 300 ] &&
18972                 error "open/close requests are not freed"
18973         return 0
18974 }
18975 run_test 209 "read-only open/close requests should be freed promptly"
18976
18977 test_210() {
18978         local pid
18979
18980         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18981         pid=$!
18982         sleep 1
18983
18984         $LFS getstripe $DIR/$tfile
18985         kill -USR1 $pid
18986         wait $pid || error "multiop failed"
18987
18988         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18989         pid=$!
18990         sleep 1
18991
18992         $LFS getstripe $DIR/$tfile
18993         kill -USR1 $pid
18994         wait $pid || error "multiop failed"
18995 }
18996 run_test 210 "lfs getstripe does not break leases"
18997
18998 test_212() {
18999         size=`date +%s`
19000         size=$((size % 8192 + 1))
19001         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19002         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19003         rm -f $DIR/f212 $DIR/f212.xyz
19004 }
19005 run_test 212 "Sendfile test ============================================"
19006
19007 test_213() {
19008         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19009         cancel_lru_locks osc
19010         lctl set_param fail_loc=0x8000040f
19011         # generate a read lock
19012         cat $DIR/$tfile > /dev/null
19013         # write to the file, it will try to cancel the above read lock.
19014         cat /etc/hosts >> $DIR/$tfile
19015 }
19016 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19017
19018 test_214() { # for bug 20133
19019         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19020         for (( i=0; i < 340; i++ )) ; do
19021                 touch $DIR/$tdir/d214c/a$i
19022         done
19023
19024         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19025         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19026         ls $DIR/d214c || error "ls $DIR/d214c failed"
19027         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19028         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19029 }
19030 run_test 214 "hash-indexed directory test - bug 20133"
19031
19032 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19033 create_lnet_proc_files() {
19034         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19035 }
19036
19037 # counterpart of create_lnet_proc_files
19038 remove_lnet_proc_files() {
19039         rm -f $TMP/lnet_$1.sys
19040 }
19041
19042 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19043 # 3rd arg as regexp for body
19044 check_lnet_proc_stats() {
19045         local l=$(cat "$TMP/lnet_$1" |wc -l)
19046         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19047
19048         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19049 }
19050
19051 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19052 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19053 # optional and can be regexp for 2nd line (lnet.routes case)
19054 check_lnet_proc_entry() {
19055         local blp=2          # blp stands for 'position of 1st line of body'
19056         [ -z "$5" ] || blp=3 # lnet.routes case
19057
19058         local l=$(cat "$TMP/lnet_$1" |wc -l)
19059         # subtracting one from $blp because the body can be empty
19060         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19061
19062         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19063                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19064
19065         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19066                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19067
19068         # bail out if any unexpected line happened
19069         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19070         [ "$?" != 0 ] || error "$2 misformatted"
19071 }
19072
19073 test_215() { # for bugs 18102, 21079, 21517
19074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19075
19076         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19077         local P='[1-9][0-9]*'           # positive numeric
19078         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19079         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19080         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19081         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19082
19083         local L1 # regexp for 1st line
19084         local L2 # regexp for 2nd line (optional)
19085         local BR # regexp for the rest (body)
19086
19087         # lnet.stats should look as 11 space-separated non-negative numerics
19088         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19089         create_lnet_proc_files "stats"
19090         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19091         remove_lnet_proc_files "stats"
19092
19093         # lnet.routes should look like this:
19094         # Routing disabled/enabled
19095         # net hops priority state router
19096         # where net is a string like tcp0, hops > 0, priority >= 0,
19097         # state is up/down,
19098         # router is a string like 192.168.1.1@tcp2
19099         L1="^Routing (disabled|enabled)$"
19100         L2="^net +hops +priority +state +router$"
19101         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19102         create_lnet_proc_files "routes"
19103         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19104         remove_lnet_proc_files "routes"
19105
19106         # lnet.routers should look like this:
19107         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19108         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19109         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19110         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19111         L1="^ref +rtr_ref +alive +router$"
19112         BR="^$P +$P +(up|down) +$NID$"
19113         create_lnet_proc_files "routers"
19114         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19115         remove_lnet_proc_files "routers"
19116
19117         # lnet.peers should look like this:
19118         # nid refs state last max rtr min tx min queue
19119         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19120         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19121         # numeric (0 or >0 or <0), queue >= 0.
19122         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19123         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19124         create_lnet_proc_files "peers"
19125         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19126         remove_lnet_proc_files "peers"
19127
19128         # lnet.buffers  should look like this:
19129         # pages count credits min
19130         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19131         L1="^pages +count +credits +min$"
19132         BR="^ +$N +$N +$I +$I$"
19133         create_lnet_proc_files "buffers"
19134         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19135         remove_lnet_proc_files "buffers"
19136
19137         # lnet.nis should look like this:
19138         # nid status alive refs peer rtr max tx min
19139         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19140         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19141         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19142         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19143         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19144         create_lnet_proc_files "nis"
19145         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19146         remove_lnet_proc_files "nis"
19147
19148         # can we successfully write to lnet.stats?
19149         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19150 }
19151 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19152
19153 test_216() { # bug 20317
19154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19155         remote_ost_nodsh && skip "remote OST with nodsh"
19156
19157         local node
19158         local facets=$(get_facets OST)
19159         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19160
19161         save_lustre_params client "osc.*.contention_seconds" > $p
19162         save_lustre_params $facets \
19163                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19164         save_lustre_params $facets \
19165                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19166         save_lustre_params $facets \
19167                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19168         clear_stats osc.*.osc_stats
19169
19170         # agressive lockless i/o settings
19171         do_nodes $(comma_list $(osts_nodes)) \
19172                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19173                         ldlm.namespaces.filter-*.contended_locks=0 \
19174                         ldlm.namespaces.filter-*.contention_seconds=60"
19175         lctl set_param -n osc.*.contention_seconds=60
19176
19177         $DIRECTIO write $DIR/$tfile 0 10 4096
19178         $CHECKSTAT -s 40960 $DIR/$tfile
19179
19180         # disable lockless i/o
19181         do_nodes $(comma_list $(osts_nodes)) \
19182                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19183                         ldlm.namespaces.filter-*.contended_locks=32 \
19184                         ldlm.namespaces.filter-*.contention_seconds=0"
19185         lctl set_param -n osc.*.contention_seconds=0
19186         clear_stats osc.*.osc_stats
19187
19188         dd if=/dev/zero of=$DIR/$tfile count=0
19189         $CHECKSTAT -s 0 $DIR/$tfile
19190
19191         restore_lustre_params <$p
19192         rm -f $p
19193         rm $DIR/$tfile
19194 }
19195 run_test 216 "check lockless direct write updates file size and kms correctly"
19196
19197 test_217() { # bug 22430
19198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19199
19200         local node
19201         local nid
19202
19203         for node in $(nodes_list); do
19204                 nid=$(host_nids_address $node $NETTYPE)
19205                 if [[ $nid = *-* ]] ; then
19206                         echo "lctl ping $(h2nettype $nid)"
19207                         lctl ping $(h2nettype $nid)
19208                 else
19209                         echo "skipping $node (no hyphen detected)"
19210                 fi
19211         done
19212 }
19213 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19214
19215 test_218() {
19216        # do directio so as not to populate the page cache
19217        log "creating a 10 Mb file"
19218        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19219        log "starting reads"
19220        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19221        log "truncating the file"
19222        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19223        log "killing dd"
19224        kill %+ || true # reads might have finished
19225        echo "wait until dd is finished"
19226        wait
19227        log "removing the temporary file"
19228        rm -rf $DIR/$tfile || error "tmp file removal failed"
19229 }
19230 run_test 218 "parallel read and truncate should not deadlock"
19231
19232 test_219() {
19233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19234
19235         # write one partial page
19236         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19237         # set no grant so vvp_io_commit_write will do sync write
19238         $LCTL set_param fail_loc=0x411
19239         # write a full page at the end of file
19240         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19241
19242         $LCTL set_param fail_loc=0
19243         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19244         $LCTL set_param fail_loc=0x411
19245         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19246
19247         # LU-4201
19248         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19249         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19250 }
19251 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19252
19253 test_220() { #LU-325
19254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19255         remote_ost_nodsh && skip "remote OST with nodsh"
19256         remote_mds_nodsh && skip "remote MDS with nodsh"
19257         remote_mgs_nodsh && skip "remote MGS with nodsh"
19258
19259         local OSTIDX=0
19260
19261         # create on MDT0000 so the last_id and next_id are correct
19262         mkdir_on_mdt0 $DIR/$tdir
19263         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19264         OST=${OST%_UUID}
19265
19266         # on the mdt's osc
19267         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19268         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19269                         osp.$mdtosc_proc1.prealloc_last_id)
19270         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19271                         osp.$mdtosc_proc1.prealloc_next_id)
19272
19273         $LFS df -i
19274
19275         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19276         #define OBD_FAIL_OST_ENOINO              0x229
19277         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19278         create_pool $FSNAME.$TESTNAME || return 1
19279         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19280
19281         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19282
19283         MDSOBJS=$((last_id - next_id))
19284         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19285
19286         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19287         echo "OST still has $count kbytes free"
19288
19289         echo "create $MDSOBJS files @next_id..."
19290         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19291
19292         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19293                         osp.$mdtosc_proc1.prealloc_last_id)
19294         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19295                         osp.$mdtosc_proc1.prealloc_next_id)
19296
19297         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19298         $LFS df -i
19299
19300         echo "cleanup..."
19301
19302         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19303         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19304
19305         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19306                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19307         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19308                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19309         echo "unlink $MDSOBJS files @$next_id..."
19310         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19311 }
19312 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19313
19314 test_221() {
19315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19316
19317         dd if=`which date` of=$MOUNT/date oflag=sync
19318         chmod +x $MOUNT/date
19319
19320         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19321         $LCTL set_param fail_loc=0x80001401
19322
19323         $MOUNT/date > /dev/null
19324         rm -f $MOUNT/date
19325 }
19326 run_test 221 "make sure fault and truncate race to not cause OOM"
19327
19328 test_222a () {
19329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19330
19331         rm -rf $DIR/$tdir
19332         test_mkdir $DIR/$tdir
19333         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19334         createmany -o $DIR/$tdir/$tfile 10
19335         cancel_lru_locks mdc
19336         cancel_lru_locks osc
19337         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19338         $LCTL set_param fail_loc=0x31a
19339         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19340         $LCTL set_param fail_loc=0
19341         rm -r $DIR/$tdir
19342 }
19343 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19344
19345 test_222b () {
19346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19347
19348         rm -rf $DIR/$tdir
19349         test_mkdir $DIR/$tdir
19350         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19351         createmany -o $DIR/$tdir/$tfile 10
19352         cancel_lru_locks mdc
19353         cancel_lru_locks osc
19354         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19355         $LCTL set_param fail_loc=0x31a
19356         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19357         $LCTL set_param fail_loc=0
19358 }
19359 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19360
19361 test_223 () {
19362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19363
19364         rm -rf $DIR/$tdir
19365         test_mkdir $DIR/$tdir
19366         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19367         createmany -o $DIR/$tdir/$tfile 10
19368         cancel_lru_locks mdc
19369         cancel_lru_locks osc
19370         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19371         $LCTL set_param fail_loc=0x31b
19372         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19373         $LCTL set_param fail_loc=0
19374         rm -r $DIR/$tdir
19375 }
19376 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19377
19378 test_224a() { # LU-1039, MRP-303
19379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19380         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19381         $LCTL set_param fail_loc=0x508
19382         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19383         $LCTL set_param fail_loc=0
19384         df $DIR
19385 }
19386 run_test 224a "Don't panic on bulk IO failure"
19387
19388 test_224bd_sub() { # LU-1039, MRP-303
19389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19390         local timeout=$1
19391
19392         shift
19393         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19394
19395         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19396
19397         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19398         cancel_lru_locks osc
19399         set_checksums 0
19400         stack_trap "set_checksums $ORIG_CSUM" EXIT
19401         local at_max_saved=0
19402
19403         # adaptive timeouts may prevent seeing the issue
19404         if at_is_enabled; then
19405                 at_max_saved=$(at_max_get mds)
19406                 at_max_set 0 mds client
19407                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19408         fi
19409
19410         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19411         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19412         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19413
19414         do_facet ost1 $LCTL set_param fail_loc=0
19415         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19416         df $DIR
19417 }
19418
19419 test_224b() {
19420         test_224bd_sub 3 error "dd failed"
19421 }
19422 run_test 224b "Don't panic on bulk IO failure"
19423
19424 test_224c() { # LU-6441
19425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19426         remote_mds_nodsh && skip "remote MDS with nodsh"
19427
19428         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19429         save_writethrough $p
19430         set_cache writethrough on
19431
19432         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19433         local at_max=$($LCTL get_param -n at_max)
19434         local timeout=$($LCTL get_param -n timeout)
19435         local test_at="at_max"
19436         local param_at="$FSNAME.sys.at_max"
19437         local test_timeout="timeout"
19438         local param_timeout="$FSNAME.sys.timeout"
19439
19440         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19441
19442         set_persistent_param_and_check client "$test_at" "$param_at" 0
19443         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19444
19445         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19446         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19447         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19448         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19449         sync
19450         do_facet ost1 "$LCTL set_param fail_loc=0"
19451
19452         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19453         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19454                 $timeout
19455
19456         $LCTL set_param -n $pages_per_rpc
19457         restore_lustre_params < $p
19458         rm -f $p
19459 }
19460 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19461
19462 test_224d() { # LU-11169
19463         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19464 }
19465 run_test 224d "Don't corrupt data on bulk IO timeout"
19466
19467 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19468 test_225a () {
19469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19470         if [ -z ${MDSSURVEY} ]; then
19471                 skip_env "mds-survey not found"
19472         fi
19473         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19474                 skip "Need MDS version at least 2.2.51"
19475
19476         local mds=$(facet_host $SINGLEMDS)
19477         local target=$(do_nodes $mds 'lctl dl' |
19478                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19479
19480         local cmd1="file_count=1000 thrhi=4"
19481         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19482         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19483         local cmd="$cmd1 $cmd2 $cmd3"
19484
19485         rm -f ${TMP}/mds_survey*
19486         echo + $cmd
19487         eval $cmd || error "mds-survey with zero-stripe failed"
19488         cat ${TMP}/mds_survey*
19489         rm -f ${TMP}/mds_survey*
19490 }
19491 run_test 225a "Metadata survey sanity with zero-stripe"
19492
19493 test_225b () {
19494         if [ -z ${MDSSURVEY} ]; then
19495                 skip_env "mds-survey not found"
19496         fi
19497         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19498                 skip "Need MDS version at least 2.2.51"
19499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19500         remote_mds_nodsh && skip "remote MDS with nodsh"
19501         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19502                 skip_env "Need to mount OST to test"
19503         fi
19504
19505         local mds=$(facet_host $SINGLEMDS)
19506         local target=$(do_nodes $mds 'lctl dl' |
19507                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19508
19509         local cmd1="file_count=1000 thrhi=4"
19510         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19511         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19512         local cmd="$cmd1 $cmd2 $cmd3"
19513
19514         rm -f ${TMP}/mds_survey*
19515         echo + $cmd
19516         eval $cmd || error "mds-survey with stripe_count failed"
19517         cat ${TMP}/mds_survey*
19518         rm -f ${TMP}/mds_survey*
19519 }
19520 run_test 225b "Metadata survey sanity with stripe_count = 1"
19521
19522 mcreate_path2fid () {
19523         local mode=$1
19524         local major=$2
19525         local minor=$3
19526         local name=$4
19527         local desc=$5
19528         local path=$DIR/$tdir/$name
19529         local fid
19530         local rc
19531         local fid_path
19532
19533         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19534                 error "cannot create $desc"
19535
19536         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19537         rc=$?
19538         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19539
19540         fid_path=$($LFS fid2path $MOUNT $fid)
19541         rc=$?
19542         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19543
19544         [ "$path" == "$fid_path" ] ||
19545                 error "fid2path returned $fid_path, expected $path"
19546
19547         echo "pass with $path and $fid"
19548 }
19549
19550 test_226a () {
19551         rm -rf $DIR/$tdir
19552         mkdir -p $DIR/$tdir
19553
19554         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19555         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19556         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19557         mcreate_path2fid 0040666 0 0 dir "directory"
19558         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19559         mcreate_path2fid 0100666 0 0 file "regular file"
19560         mcreate_path2fid 0120666 0 0 link "symbolic link"
19561         mcreate_path2fid 0140666 0 0 sock "socket"
19562 }
19563 run_test 226a "call path2fid and fid2path on files of all type"
19564
19565 test_226b () {
19566         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19567
19568         local MDTIDX=1
19569
19570         rm -rf $DIR/$tdir
19571         mkdir -p $DIR/$tdir
19572         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19573                 error "create remote directory failed"
19574         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19575         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19576                                 "character special file (null)"
19577         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19578                                 "character special file (no device)"
19579         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19580         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19581                                 "block special file (loop)"
19582         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19583         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19584         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19585 }
19586 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19587
19588 test_226c () {
19589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19590         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19591                 skip "Need MDS version at least 2.13.55"
19592
19593         local submnt=/mnt/submnt
19594         local srcfile=/etc/passwd
19595         local dstfile=$submnt/passwd
19596         local path
19597         local fid
19598
19599         rm -rf $DIR/$tdir
19600         rm -rf $submnt
19601         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19602                 error "create remote directory failed"
19603         mkdir -p $submnt || error "create $submnt failed"
19604         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19605                 error "mount $submnt failed"
19606         stack_trap "umount $submnt" EXIT
19607
19608         cp $srcfile $dstfile
19609         fid=$($LFS path2fid $dstfile)
19610         path=$($LFS fid2path $submnt "$fid")
19611         [ "$path" = "$dstfile" ] ||
19612                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19613 }
19614 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19615
19616 # LU-1299 Executing or running ldd on a truncated executable does not
19617 # cause an out-of-memory condition.
19618 test_227() {
19619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19620         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19621
19622         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19623         chmod +x $MOUNT/date
19624
19625         $MOUNT/date > /dev/null
19626         ldd $MOUNT/date > /dev/null
19627         rm -f $MOUNT/date
19628 }
19629 run_test 227 "running truncated executable does not cause OOM"
19630
19631 # LU-1512 try to reuse idle OI blocks
19632 test_228a() {
19633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19634         remote_mds_nodsh && skip "remote MDS with nodsh"
19635         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19636
19637         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19638         local myDIR=$DIR/$tdir
19639
19640         mkdir -p $myDIR
19641         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19642         $LCTL set_param fail_loc=0x80001002
19643         createmany -o $myDIR/t- 10000
19644         $LCTL set_param fail_loc=0
19645         # The guard is current the largest FID holder
19646         touch $myDIR/guard
19647         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19648                     tr -d '[')
19649         local IDX=$(($SEQ % 64))
19650
19651         do_facet $SINGLEMDS sync
19652         # Make sure journal flushed.
19653         sleep 6
19654         local blk1=$(do_facet $SINGLEMDS \
19655                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19656                      grep Blockcount | awk '{print $4}')
19657
19658         # Remove old files, some OI blocks will become idle.
19659         unlinkmany $myDIR/t- 10000
19660         # Create new files, idle OI blocks should be reused.
19661         createmany -o $myDIR/t- 2000
19662         do_facet $SINGLEMDS sync
19663         # Make sure journal flushed.
19664         sleep 6
19665         local blk2=$(do_facet $SINGLEMDS \
19666                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19667                      grep Blockcount | awk '{print $4}')
19668
19669         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19670 }
19671 run_test 228a "try to reuse idle OI blocks"
19672
19673 test_228b() {
19674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19675         remote_mds_nodsh && skip "remote MDS with nodsh"
19676         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19677
19678         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19679         local myDIR=$DIR/$tdir
19680
19681         mkdir -p $myDIR
19682         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19683         $LCTL set_param fail_loc=0x80001002
19684         createmany -o $myDIR/t- 10000
19685         $LCTL set_param fail_loc=0
19686         # The guard is current the largest FID holder
19687         touch $myDIR/guard
19688         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19689                     tr -d '[')
19690         local IDX=$(($SEQ % 64))
19691
19692         do_facet $SINGLEMDS sync
19693         # Make sure journal flushed.
19694         sleep 6
19695         local blk1=$(do_facet $SINGLEMDS \
19696                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19697                      grep Blockcount | awk '{print $4}')
19698
19699         # Remove old files, some OI blocks will become idle.
19700         unlinkmany $myDIR/t- 10000
19701
19702         # stop the MDT
19703         stop $SINGLEMDS || error "Fail to stop MDT."
19704         # remount the MDT
19705         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19706                 error "Fail to start MDT."
19707
19708         df $MOUNT || error "Fail to df."
19709         # Create new files, idle OI blocks should be reused.
19710         createmany -o $myDIR/t- 2000
19711         do_facet $SINGLEMDS sync
19712         # Make sure journal flushed.
19713         sleep 6
19714         local blk2=$(do_facet $SINGLEMDS \
19715                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19716                      grep Blockcount | awk '{print $4}')
19717
19718         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19719 }
19720 run_test 228b "idle OI blocks can be reused after MDT restart"
19721
19722 #LU-1881
19723 test_228c() {
19724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19725         remote_mds_nodsh && skip "remote MDS with nodsh"
19726         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19727
19728         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19729         local myDIR=$DIR/$tdir
19730
19731         mkdir -p $myDIR
19732         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19733         $LCTL set_param fail_loc=0x80001002
19734         # 20000 files can guarantee there are index nodes in the OI file
19735         createmany -o $myDIR/t- 20000
19736         $LCTL set_param fail_loc=0
19737         # The guard is current the largest FID holder
19738         touch $myDIR/guard
19739         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19740                     tr -d '[')
19741         local IDX=$(($SEQ % 64))
19742
19743         do_facet $SINGLEMDS sync
19744         # Make sure journal flushed.
19745         sleep 6
19746         local blk1=$(do_facet $SINGLEMDS \
19747                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19748                      grep Blockcount | awk '{print $4}')
19749
19750         # Remove old files, some OI blocks will become idle.
19751         unlinkmany $myDIR/t- 20000
19752         rm -f $myDIR/guard
19753         # The OI file should become empty now
19754
19755         # Create new files, idle OI blocks should be reused.
19756         createmany -o $myDIR/t- 2000
19757         do_facet $SINGLEMDS sync
19758         # Make sure journal flushed.
19759         sleep 6
19760         local blk2=$(do_facet $SINGLEMDS \
19761                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19762                      grep Blockcount | awk '{print $4}')
19763
19764         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19765 }
19766 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19767
19768 test_229() { # LU-2482, LU-3448
19769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19770         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19771         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19772                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19773
19774         rm -f $DIR/$tfile
19775
19776         # Create a file with a released layout and stripe count 2.
19777         $MULTIOP $DIR/$tfile H2c ||
19778                 error "failed to create file with released layout"
19779
19780         $LFS getstripe -v $DIR/$tfile
19781
19782         local pattern=$($LFS getstripe -L $DIR/$tfile)
19783         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19784
19785         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19786                 error "getstripe"
19787         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19788         stat $DIR/$tfile || error "failed to stat released file"
19789
19790         chown $RUNAS_ID $DIR/$tfile ||
19791                 error "chown $RUNAS_ID $DIR/$tfile failed"
19792
19793         chgrp $RUNAS_ID $DIR/$tfile ||
19794                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19795
19796         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19797         rm $DIR/$tfile || error "failed to remove released file"
19798 }
19799 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19800
19801 test_230a() {
19802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19803         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19804         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19805                 skip "Need MDS version at least 2.11.52"
19806
19807         local MDTIDX=1
19808
19809         test_mkdir $DIR/$tdir
19810         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19811         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19812         [ $mdt_idx -ne 0 ] &&
19813                 error "create local directory on wrong MDT $mdt_idx"
19814
19815         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19816                         error "create remote directory failed"
19817         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19818         [ $mdt_idx -ne $MDTIDX ] &&
19819                 error "create remote directory on wrong MDT $mdt_idx"
19820
19821         createmany -o $DIR/$tdir/test_230/t- 10 ||
19822                 error "create files on remote directory failed"
19823         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19824         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19825         rm -r $DIR/$tdir || error "unlink remote directory failed"
19826 }
19827 run_test 230a "Create remote directory and files under the remote directory"
19828
19829 test_230b() {
19830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19831         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19832         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19833                 skip "Need MDS version at least 2.11.52"
19834
19835         local MDTIDX=1
19836         local mdt_index
19837         local i
19838         local file
19839         local pid
19840         local stripe_count
19841         local migrate_dir=$DIR/$tdir/migrate_dir
19842         local other_dir=$DIR/$tdir/other_dir
19843
19844         test_mkdir $DIR/$tdir
19845         test_mkdir -i0 -c1 $migrate_dir
19846         test_mkdir -i0 -c1 $other_dir
19847         for ((i=0; i<10; i++)); do
19848                 mkdir -p $migrate_dir/dir_${i}
19849                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19850                         error "create files under remote dir failed $i"
19851         done
19852
19853         cp /etc/passwd $migrate_dir/$tfile
19854         cp /etc/passwd $other_dir/$tfile
19855         chattr +SAD $migrate_dir
19856         chattr +SAD $migrate_dir/$tfile
19857
19858         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19859         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19860         local old_dir_mode=$(stat -c%f $migrate_dir)
19861         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19862
19863         mkdir -p $migrate_dir/dir_default_stripe2
19864         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19865         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19866
19867         mkdir -p $other_dir
19868         ln $migrate_dir/$tfile $other_dir/luna
19869         ln $migrate_dir/$tfile $migrate_dir/sofia
19870         ln $other_dir/$tfile $migrate_dir/david
19871         ln -s $migrate_dir/$tfile $other_dir/zachary
19872         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19873         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19874
19875         local len
19876         local lnktgt
19877
19878         # inline symlink
19879         for len in 58 59 60; do
19880                 lnktgt=$(str_repeat 'l' $len)
19881                 touch $migrate_dir/$lnktgt
19882                 ln -s $lnktgt $migrate_dir/${len}char_ln
19883         done
19884
19885         # PATH_MAX
19886         for len in 4094 4095; do
19887                 lnktgt=$(str_repeat 'l' $len)
19888                 ln -s $lnktgt $migrate_dir/${len}char_ln
19889         done
19890
19891         # NAME_MAX
19892         for len in 254 255; do
19893                 touch $migrate_dir/$(str_repeat 'l' $len)
19894         done
19895
19896         $LFS migrate -m $MDTIDX $migrate_dir ||
19897                 error "fails on migrating remote dir to MDT1"
19898
19899         echo "migratate to MDT1, then checking.."
19900         for ((i = 0; i < 10; i++)); do
19901                 for file in $(find $migrate_dir/dir_${i}); do
19902                         mdt_index=$($LFS getstripe -m $file)
19903                         # broken symlink getstripe will fail
19904                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19905                                 error "$file is not on MDT${MDTIDX}"
19906                 done
19907         done
19908
19909         # the multiple link file should still in MDT0
19910         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19911         [ $mdt_index == 0 ] ||
19912                 error "$file is not on MDT${MDTIDX}"
19913
19914         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19915         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19916                 error " expect $old_dir_flag get $new_dir_flag"
19917
19918         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19919         [ "$old_file_flag" = "$new_file_flag" ] ||
19920                 error " expect $old_file_flag get $new_file_flag"
19921
19922         local new_dir_mode=$(stat -c%f $migrate_dir)
19923         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19924                 error "expect mode $old_dir_mode get $new_dir_mode"
19925
19926         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19927         [ "$old_file_mode" = "$new_file_mode" ] ||
19928                 error "expect mode $old_file_mode get $new_file_mode"
19929
19930         diff /etc/passwd $migrate_dir/$tfile ||
19931                 error "$tfile different after migration"
19932
19933         diff /etc/passwd $other_dir/luna ||
19934                 error "luna different after migration"
19935
19936         diff /etc/passwd $migrate_dir/sofia ||
19937                 error "sofia different after migration"
19938
19939         diff /etc/passwd $migrate_dir/david ||
19940                 error "david different after migration"
19941
19942         diff /etc/passwd $other_dir/zachary ||
19943                 error "zachary different after migration"
19944
19945         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19946                 error "${tfile}_ln different after migration"
19947
19948         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19949                 error "${tfile}_ln_other different after migration"
19950
19951         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19952         [ $stripe_count = 2 ] ||
19953                 error "dir strpe_count $d != 2 after migration."
19954
19955         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19956         [ $stripe_count = 2 ] ||
19957                 error "file strpe_count $d != 2 after migration."
19958
19959         #migrate back to MDT0
19960         MDTIDX=0
19961
19962         $LFS migrate -m $MDTIDX $migrate_dir ||
19963                 error "fails on migrating remote dir to MDT0"
19964
19965         echo "migrate back to MDT0, checking.."
19966         for file in $(find $migrate_dir); do
19967                 mdt_index=$($LFS getstripe -m $file)
19968                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19969                         error "$file is not on MDT${MDTIDX}"
19970         done
19971
19972         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19973         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19974                 error " expect $old_dir_flag get $new_dir_flag"
19975
19976         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19977         [ "$old_file_flag" = "$new_file_flag" ] ||
19978                 error " expect $old_file_flag get $new_file_flag"
19979
19980         local new_dir_mode=$(stat -c%f $migrate_dir)
19981         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19982                 error "expect mode $old_dir_mode get $new_dir_mode"
19983
19984         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19985         [ "$old_file_mode" = "$new_file_mode" ] ||
19986                 error "expect mode $old_file_mode get $new_file_mode"
19987
19988         diff /etc/passwd ${migrate_dir}/$tfile ||
19989                 error "$tfile different after migration"
19990
19991         diff /etc/passwd ${other_dir}/luna ||
19992                 error "luna different after migration"
19993
19994         diff /etc/passwd ${migrate_dir}/sofia ||
19995                 error "sofia different after migration"
19996
19997         diff /etc/passwd ${other_dir}/zachary ||
19998                 error "zachary different after migration"
19999
20000         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20001                 error "${tfile}_ln different after migration"
20002
20003         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20004                 error "${tfile}_ln_other different after migration"
20005
20006         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20007         [ $stripe_count = 2 ] ||
20008                 error "dir strpe_count $d != 2 after migration."
20009
20010         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20011         [ $stripe_count = 2 ] ||
20012                 error "file strpe_count $d != 2 after migration."
20013
20014         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20015 }
20016 run_test 230b "migrate directory"
20017
20018 test_230c() {
20019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20020         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20021         remote_mds_nodsh && skip "remote MDS with nodsh"
20022         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20023                 skip "Need MDS version at least 2.11.52"
20024
20025         local MDTIDX=1
20026         local total=3
20027         local mdt_index
20028         local file
20029         local migrate_dir=$DIR/$tdir/migrate_dir
20030
20031         #If migrating directory fails in the middle, all entries of
20032         #the directory is still accessiable.
20033         test_mkdir $DIR/$tdir
20034         test_mkdir -i0 -c1 $migrate_dir
20035         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20036         stat $migrate_dir
20037         createmany -o $migrate_dir/f $total ||
20038                 error "create files under ${migrate_dir} failed"
20039
20040         # fail after migrating top dir, and this will fail only once, so the
20041         # first sub file migration will fail (currently f3), others succeed.
20042         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20043         do_facet mds1 lctl set_param fail_loc=0x1801
20044         local t=$(ls $migrate_dir | wc -l)
20045         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20046                 error "migrate should fail"
20047         local u=$(ls $migrate_dir | wc -l)
20048         [ "$u" == "$t" ] || error "$u != $t during migration"
20049
20050         # add new dir/file should succeed
20051         mkdir $migrate_dir/dir ||
20052                 error "mkdir failed under migrating directory"
20053         touch $migrate_dir/file ||
20054                 error "create file failed under migrating directory"
20055
20056         # add file with existing name should fail
20057         for file in $migrate_dir/f*; do
20058                 stat $file > /dev/null || error "stat $file failed"
20059                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20060                         error "open(O_CREAT|O_EXCL) $file should fail"
20061                 $MULTIOP $file m && error "create $file should fail"
20062                 touch $DIR/$tdir/remote_dir/$tfile ||
20063                         error "touch $tfile failed"
20064                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20065                         error "link $file should fail"
20066                 mdt_index=$($LFS getstripe -m $file)
20067                 if [ $mdt_index == 0 ]; then
20068                         # file failed to migrate is not allowed to rename to
20069                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20070                                 error "rename to $file should fail"
20071                 else
20072                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20073                                 error "rename to $file failed"
20074                 fi
20075                 echo hello >> $file || error "write $file failed"
20076         done
20077
20078         # resume migration with different options should fail
20079         $LFS migrate -m 0 $migrate_dir &&
20080                 error "migrate -m 0 $migrate_dir should fail"
20081
20082         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20083                 error "migrate -c 2 $migrate_dir should fail"
20084
20085         # resume migration should succeed
20086         $LFS migrate -m $MDTIDX $migrate_dir ||
20087                 error "migrate $migrate_dir failed"
20088
20089         echo "Finish migration, then checking.."
20090         for file in $(find $migrate_dir); do
20091                 mdt_index=$($LFS getstripe -m $file)
20092                 [ $mdt_index == $MDTIDX ] ||
20093                         error "$file is not on MDT${MDTIDX}"
20094         done
20095
20096         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20097 }
20098 run_test 230c "check directory accessiblity if migration failed"
20099
20100 test_230d() {
20101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20102         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20103         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20104                 skip "Need MDS version at least 2.11.52"
20105         # LU-11235
20106         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20107
20108         local migrate_dir=$DIR/$tdir/migrate_dir
20109         local old_index
20110         local new_index
20111         local old_count
20112         local new_count
20113         local new_hash
20114         local mdt_index
20115         local i
20116         local j
20117
20118         old_index=$((RANDOM % MDSCOUNT))
20119         old_count=$((MDSCOUNT - old_index))
20120         new_index=$((RANDOM % MDSCOUNT))
20121         new_count=$((MDSCOUNT - new_index))
20122         new_hash=1 # for all_char
20123
20124         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20125         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20126
20127         test_mkdir $DIR/$tdir
20128         test_mkdir -i $old_index -c $old_count $migrate_dir
20129
20130         for ((i=0; i<100; i++)); do
20131                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20132                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20133                         error "create files under remote dir failed $i"
20134         done
20135
20136         echo -n "Migrate from MDT$old_index "
20137         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20138         echo -n "to MDT$new_index"
20139         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20140         echo
20141
20142         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20143         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20144                 error "migrate remote dir error"
20145
20146         echo "Finish migration, then checking.."
20147         for file in $(find $migrate_dir -maxdepth 1); do
20148                 mdt_index=$($LFS getstripe -m $file)
20149                 if [ $mdt_index -lt $new_index ] ||
20150                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20151                         error "$file is on MDT$mdt_index"
20152                 fi
20153         done
20154
20155         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20156 }
20157 run_test 230d "check migrate big directory"
20158
20159 test_230e() {
20160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20161         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20162         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20163                 skip "Need MDS version at least 2.11.52"
20164
20165         local i
20166         local j
20167         local a_fid
20168         local b_fid
20169
20170         mkdir_on_mdt0 $DIR/$tdir
20171         mkdir $DIR/$tdir/migrate_dir
20172         mkdir $DIR/$tdir/other_dir
20173         touch $DIR/$tdir/migrate_dir/a
20174         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20175         ls $DIR/$tdir/other_dir
20176
20177         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20178                 error "migrate dir fails"
20179
20180         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20181         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20182
20183         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20184         [ $mdt_index == 0 ] || error "a is not on MDT0"
20185
20186         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20187                 error "migrate dir fails"
20188
20189         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20190         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20191
20192         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20193         [ $mdt_index == 1 ] || error "a is not on MDT1"
20194
20195         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20196         [ $mdt_index == 1 ] || error "b is not on MDT1"
20197
20198         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20199         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20200
20201         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20202
20203         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20204 }
20205 run_test 230e "migrate mulitple local link files"
20206
20207 test_230f() {
20208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20210         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20211                 skip "Need MDS version at least 2.11.52"
20212
20213         local a_fid
20214         local ln_fid
20215
20216         mkdir -p $DIR/$tdir
20217         mkdir $DIR/$tdir/migrate_dir
20218         $LFS mkdir -i1 $DIR/$tdir/other_dir
20219         touch $DIR/$tdir/migrate_dir/a
20220         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20221         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20222         ls $DIR/$tdir/other_dir
20223
20224         # a should be migrated to MDT1, since no other links on MDT0
20225         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20226                 error "#1 migrate dir fails"
20227         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20228         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20229         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20230         [ $mdt_index == 1 ] || error "a is not on MDT1"
20231
20232         # a should stay on MDT1, because it is a mulitple link file
20233         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20234                 error "#2 migrate dir fails"
20235         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20236         [ $mdt_index == 1 ] || error "a is not on MDT1"
20237
20238         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20239                 error "#3 migrate dir fails"
20240
20241         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20242         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20243         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20244
20245         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20246         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20247
20248         # a should be migrated to MDT0, since no other links on MDT1
20249         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20250                 error "#4 migrate dir fails"
20251         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20252         [ $mdt_index == 0 ] || error "a is not on MDT0"
20253
20254         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20255 }
20256 run_test 230f "migrate mulitple remote link files"
20257
20258 test_230g() {
20259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20261         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20262                 skip "Need MDS version at least 2.11.52"
20263
20264         mkdir -p $DIR/$tdir/migrate_dir
20265
20266         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20267                 error "migrating dir to non-exist MDT succeeds"
20268         true
20269 }
20270 run_test 230g "migrate dir to non-exist MDT"
20271
20272 test_230h() {
20273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20274         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20275         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20276                 skip "Need MDS version at least 2.11.52"
20277
20278         local mdt_index
20279
20280         mkdir -p $DIR/$tdir/migrate_dir
20281
20282         $LFS migrate -m1 $DIR &&
20283                 error "migrating mountpoint1 should fail"
20284
20285         $LFS migrate -m1 $DIR/$tdir/.. &&
20286                 error "migrating mountpoint2 should fail"
20287
20288         # same as mv
20289         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20290                 error "migrating $tdir/migrate_dir/.. should fail"
20291
20292         true
20293 }
20294 run_test 230h "migrate .. and root"
20295
20296 test_230i() {
20297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20298         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20299         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20300                 skip "Need MDS version at least 2.11.52"
20301
20302         mkdir -p $DIR/$tdir/migrate_dir
20303
20304         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20305                 error "migration fails with a tailing slash"
20306
20307         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20308                 error "migration fails with two tailing slashes"
20309 }
20310 run_test 230i "lfs migrate -m tolerates trailing slashes"
20311
20312 test_230j() {
20313         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20314         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20315                 skip "Need MDS version at least 2.11.52"
20316
20317         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20318         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20319                 error "create $tfile failed"
20320         cat /etc/passwd > $DIR/$tdir/$tfile
20321
20322         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20323
20324         cmp /etc/passwd $DIR/$tdir/$tfile ||
20325                 error "DoM file mismatch after migration"
20326 }
20327 run_test 230j "DoM file data not changed after dir migration"
20328
20329 test_230k() {
20330         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20331         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20332                 skip "Need MDS version at least 2.11.56"
20333
20334         local total=20
20335         local files_on_starting_mdt=0
20336
20337         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20338         $LFS getdirstripe $DIR/$tdir
20339         for i in $(seq $total); do
20340                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20341                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20342                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20343         done
20344
20345         echo "$files_on_starting_mdt files on MDT0"
20346
20347         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20348         $LFS getdirstripe $DIR/$tdir
20349
20350         files_on_starting_mdt=0
20351         for i in $(seq $total); do
20352                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20353                         error "file $tfile.$i mismatch after migration"
20354                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20355                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20356         done
20357
20358         echo "$files_on_starting_mdt files on MDT1 after migration"
20359         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20360
20361         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20362         $LFS getdirstripe $DIR/$tdir
20363
20364         files_on_starting_mdt=0
20365         for i in $(seq $total); do
20366                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20367                         error "file $tfile.$i mismatch after 2nd migration"
20368                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20369                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20370         done
20371
20372         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20373         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20374
20375         true
20376 }
20377 run_test 230k "file data not changed after dir migration"
20378
20379 test_230l() {
20380         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20381         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20382                 skip "Need MDS version at least 2.11.56"
20383
20384         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20385         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20386                 error "create files under remote dir failed $i"
20387         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20388 }
20389 run_test 230l "readdir between MDTs won't crash"
20390
20391 test_230m() {
20392         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20393         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20394                 skip "Need MDS version at least 2.11.56"
20395
20396         local MDTIDX=1
20397         local mig_dir=$DIR/$tdir/migrate_dir
20398         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20399         local shortstr="b"
20400         local val
20401
20402         echo "Creating files and dirs with xattrs"
20403         test_mkdir $DIR/$tdir
20404         test_mkdir -i0 -c1 $mig_dir
20405         mkdir $mig_dir/dir
20406         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20407                 error "cannot set xattr attr1 on dir"
20408         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20409                 error "cannot set xattr attr2 on dir"
20410         touch $mig_dir/dir/f0
20411         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20412                 error "cannot set xattr attr1 on file"
20413         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20414                 error "cannot set xattr attr2 on file"
20415         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20416         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20417         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20418         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20419         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20420         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20421         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20422         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20423         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20424
20425         echo "Migrating to MDT1"
20426         $LFS migrate -m $MDTIDX $mig_dir ||
20427                 error "fails on migrating dir to MDT1"
20428
20429         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20430         echo "Checking xattrs"
20431         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20432         [ "$val" = $longstr ] ||
20433                 error "expecting xattr1 $longstr on dir, found $val"
20434         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20435         [ "$val" = $shortstr ] ||
20436                 error "expecting xattr2 $shortstr on dir, found $val"
20437         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20438         [ "$val" = $longstr ] ||
20439                 error "expecting xattr1 $longstr on file, found $val"
20440         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20441         [ "$val" = $shortstr ] ||
20442                 error "expecting xattr2 $shortstr on file, found $val"
20443 }
20444 run_test 230m "xattrs not changed after dir migration"
20445
20446 test_230n() {
20447         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20448         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20449                 skip "Need MDS version at least 2.13.53"
20450
20451         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20452         cat /etc/hosts > $DIR/$tdir/$tfile
20453         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20454         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20455
20456         cmp /etc/hosts $DIR/$tdir/$tfile ||
20457                 error "File data mismatch after migration"
20458 }
20459 run_test 230n "Dir migration with mirrored file"
20460
20461 test_230o() {
20462         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20463         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20464                 skip "Need MDS version at least 2.13.52"
20465
20466         local mdts=$(comma_list $(mdts_nodes))
20467         local timeout=100
20468         local restripe_status
20469         local delta
20470         local i
20471
20472         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20473
20474         # in case "crush" hash type is not set
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         mkdir $DIR/$tdir
20484         createmany -m $DIR/$tdir/f 100 ||
20485                 error "create files under remote dir failed $i"
20486         createmany -d $DIR/$tdir/d 100 ||
20487                 error "create dirs under remote dir failed $i"
20488
20489         for i in $(seq 2 $MDSCOUNT); do
20490                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20491                 $LFS setdirstripe -c $i $DIR/$tdir ||
20492                         error "split -c $i $tdir failed"
20493                 wait_update $HOSTNAME \
20494                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20495                         error "dir split not finished"
20496                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20497                         awk '/migrate/ {sum += $2} END { print sum }')
20498                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20499                 # delta is around total_files/stripe_count
20500                 (( $delta < 200 / (i - 1) + 4 )) ||
20501                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20502         done
20503 }
20504 run_test 230o "dir split"
20505
20506 test_230p() {
20507         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20508         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20509                 skip "Need MDS version at least 2.13.52"
20510
20511         local mdts=$(comma_list $(mdts_nodes))
20512         local timeout=100
20513         local restripe_status
20514         local delta
20515         local c
20516
20517         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20518
20519         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20520
20521         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20522                            mdt.*MDT0000.enable_dir_restripe)
20523         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20524         stack_trap "do_nodes $mdts $LCTL set_param \
20525                     mdt.*.enable_dir_restripe=$restripe_status"
20526
20527         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20528         createmany -m $DIR/$tdir/f 100 ||
20529                 error "create files under remote dir failed"
20530         createmany -d $DIR/$tdir/d 100 ||
20531                 error "create dirs under remote dir failed"
20532
20533         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20534                 local mdt_hash="crush"
20535
20536                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20537                 $LFS setdirstripe -c $c $DIR/$tdir ||
20538                         error "split -c $c $tdir failed"
20539                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20540                         mdt_hash="$mdt_hash,fixed"
20541                 elif [ $c -eq 1 ]; then
20542                         mdt_hash="none"
20543                 fi
20544                 wait_update $HOSTNAME \
20545                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20546                         error "dir merge not finished"
20547                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20548                         awk '/migrate/ {sum += $2} END { print sum }')
20549                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20550                 # delta is around total_files/stripe_count
20551                 (( delta < 200 / c + 4 )) ||
20552                         error "$delta files migrated >= $((200 / c + 4))"
20553         done
20554 }
20555 run_test 230p "dir merge"
20556
20557 test_230q() {
20558         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20559         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20560                 skip "Need MDS version at least 2.13.52"
20561
20562         local mdts=$(comma_list $(mdts_nodes))
20563         local saved_threshold=$(do_facet mds1 \
20564                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20565         local saved_delta=$(do_facet mds1 \
20566                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20567         local threshold=100
20568         local delta=2
20569         local total=0
20570         local stripe_count=0
20571         local stripe_index
20572         local nr_files
20573         local create
20574
20575         # test with fewer files on ZFS
20576         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20577
20578         stack_trap "do_nodes $mdts $LCTL set_param \
20579                     mdt.*.dir_split_count=$saved_threshold"
20580         stack_trap "do_nodes $mdts $LCTL set_param \
20581                     mdt.*.dir_split_delta=$saved_delta"
20582         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20583         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20584         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20585         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20586         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20587         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20588
20589         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20590         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20591
20592         create=$((threshold * 3 / 2))
20593         while [ $stripe_count -lt $MDSCOUNT ]; do
20594                 createmany -m $DIR/$tdir/f $total $create ||
20595                         error "create sub files failed"
20596                 stat $DIR/$tdir > /dev/null
20597                 total=$((total + create))
20598                 stripe_count=$((stripe_count + delta))
20599                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20600
20601                 wait_update $HOSTNAME \
20602                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20603                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20604
20605                 wait_update $HOSTNAME \
20606                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20607                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20608
20609                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20610                 echo "$nr_files/$total files on MDT$stripe_index after split"
20611                 # allow 10% margin of imbalance with crush hash
20612                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20613                         error "$nr_files files on MDT$stripe_index after split"
20614
20615                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20616                 [ $nr_files -eq $total ] ||
20617                         error "total sub files $nr_files != $total"
20618         done
20619
20620         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20621
20622         echo "fixed layout directory won't auto split"
20623         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20624         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20625                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20626         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20627                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20628 }
20629 run_test 230q "dir auto split"
20630
20631 test_230r() {
20632         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20633         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20634         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20635                 skip "Need MDS version at least 2.13.54"
20636
20637         # maximum amount of local locks:
20638         # parent striped dir - 2 locks
20639         # new stripe in parent to migrate to - 1 lock
20640         # source and target - 2 locks
20641         # Total 5 locks for regular file
20642         mkdir -p $DIR/$tdir
20643         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20644         touch $DIR/$tdir/dir1/eee
20645
20646         # create 4 hardlink for 4 more locks
20647         # Total: 9 locks > RS_MAX_LOCKS (8)
20648         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20649         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20650         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20651         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20652         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20653         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20654         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20655         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20656
20657         cancel_lru_locks mdc
20658
20659         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20660                 error "migrate dir fails"
20661
20662         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20663 }
20664 run_test 230r "migrate with too many local locks"
20665
20666 test_230s() {
20667         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20668                 skip "Need MDS version at least 2.14.52"
20669
20670         local mdts=$(comma_list $(mdts_nodes))
20671         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20672                                 mdt.*MDT0000.enable_dir_restripe)
20673
20674         stack_trap "do_nodes $mdts $LCTL set_param \
20675                     mdt.*.enable_dir_restripe=$restripe_status"
20676
20677         local st
20678         for st in 0 1; do
20679                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20680                 test_mkdir $DIR/$tdir
20681                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20682                         error "$LFS mkdir should return EEXIST if target exists"
20683                 rmdir $DIR/$tdir
20684         done
20685 }
20686 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20687
20688 test_230t()
20689 {
20690         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20691         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20692                 skip "Need MDS version at least 2.14.50"
20693
20694         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20695         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20696         $LFS project -p 1 -s $DIR/$tdir ||
20697                 error "set $tdir project id failed"
20698         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20699                 error "set subdir project id failed"
20700         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20701 }
20702 run_test 230t "migrate directory with project ID set"
20703
20704 test_230u()
20705 {
20706         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20707         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20708                 skip "Need MDS version at least 2.14.53"
20709
20710         local count
20711
20712         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20713         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20714         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20715         for i in $(seq 0 $((MDSCOUNT - 1))); do
20716                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20717                 echo "$count dirs migrated to MDT$i"
20718         done
20719         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20720         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20721 }
20722 run_test 230u "migrate directory by QOS"
20723
20724 test_230v()
20725 {
20726         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20727         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20728                 skip "Need MDS version at least 2.14.53"
20729
20730         local count
20731
20732         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20733         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20734         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20735         for i in $(seq 0 $((MDSCOUNT - 1))); do
20736                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20737                 echo "$count subdirs migrated to MDT$i"
20738                 (( i == 3 )) && (( count > 0 )) &&
20739                         error "subdir shouldn't be migrated to MDT3"
20740         done
20741         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20742         (( count == 3 )) || error "dirs migrated to $count MDTs"
20743 }
20744 run_test 230v "subdir migrated to the MDT where its parent is located"
20745
20746 test_230w() {
20747         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20748         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20749                 skip "Need MDS version at least 2.14.53"
20750
20751         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20752
20753         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20754                 error "migrate failed"
20755
20756         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20757                 error "$tdir stripe count mismatch"
20758
20759         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20760                 error "$tdir/sub is striped"
20761 }
20762 run_test 230w "non-recursive mode dir migration"
20763
20764 test_231a()
20765 {
20766         # For simplicity this test assumes that max_pages_per_rpc
20767         # is the same across all OSCs
20768         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20769         local bulk_size=$((max_pages * PAGE_SIZE))
20770         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20771                                        head -n 1)
20772
20773         mkdir -p $DIR/$tdir
20774         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20775                 error "failed to set stripe with -S ${brw_size}M option"
20776
20777         # clear the OSC stats
20778         $LCTL set_param osc.*.stats=0 &>/dev/null
20779         stop_writeback
20780
20781         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20782         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20783                 oflag=direct &>/dev/null || error "dd failed"
20784
20785         sync; sleep 1; sync # just to be safe
20786         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20787         if [ x$nrpcs != "x1" ]; then
20788                 $LCTL get_param osc.*.stats
20789                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20790         fi
20791
20792         start_writeback
20793         # Drop the OSC cache, otherwise we will read from it
20794         cancel_lru_locks osc
20795
20796         # clear the OSC stats
20797         $LCTL set_param osc.*.stats=0 &>/dev/null
20798
20799         # Client reads $bulk_size.
20800         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20801                 iflag=direct &>/dev/null || error "dd failed"
20802
20803         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20804         if [ x$nrpcs != "x1" ]; then
20805                 $LCTL get_param osc.*.stats
20806                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20807         fi
20808 }
20809 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20810
20811 test_231b() {
20812         mkdir -p $DIR/$tdir
20813         local i
20814         for i in {0..1023}; do
20815                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20816                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20817                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20818         done
20819         sync
20820 }
20821 run_test 231b "must not assert on fully utilized OST request buffer"
20822
20823 test_232a() {
20824         mkdir -p $DIR/$tdir
20825         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20826
20827         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20828         do_facet ost1 $LCTL set_param fail_loc=0x31c
20829
20830         # ignore dd failure
20831         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20832
20833         do_facet ost1 $LCTL set_param fail_loc=0
20834         umount_client $MOUNT || error "umount failed"
20835         mount_client $MOUNT || error "mount failed"
20836         stop ost1 || error "cannot stop ost1"
20837         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20838 }
20839 run_test 232a "failed lock should not block umount"
20840
20841 test_232b() {
20842         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20843                 skip "Need MDS version at least 2.10.58"
20844
20845         mkdir -p $DIR/$tdir
20846         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20847         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20848         sync
20849         cancel_lru_locks osc
20850
20851         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20852         do_facet ost1 $LCTL set_param fail_loc=0x31c
20853
20854         # ignore failure
20855         $LFS data_version $DIR/$tdir/$tfile || true
20856
20857         do_facet ost1 $LCTL set_param fail_loc=0
20858         umount_client $MOUNT || error "umount failed"
20859         mount_client $MOUNT || error "mount failed"
20860         stop ost1 || error "cannot stop ost1"
20861         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20862 }
20863 run_test 232b "failed data version lock should not block umount"
20864
20865 test_233a() {
20866         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20867                 skip "Need MDS version at least 2.3.64"
20868         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20869
20870         local fid=$($LFS path2fid $MOUNT)
20871
20872         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20873                 error "cannot access $MOUNT using its FID '$fid'"
20874 }
20875 run_test 233a "checking that OBF of the FS root succeeds"
20876
20877 test_233b() {
20878         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20879                 skip "Need MDS version at least 2.5.90"
20880         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20881
20882         local fid=$($LFS path2fid $MOUNT/.lustre)
20883
20884         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20885                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20886
20887         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20888         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20889                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20890 }
20891 run_test 233b "checking that OBF of the FS .lustre succeeds"
20892
20893 test_234() {
20894         local p="$TMP/sanityN-$TESTNAME.parameters"
20895         save_lustre_params client "llite.*.xattr_cache" > $p
20896         lctl set_param llite.*.xattr_cache 1 ||
20897                 skip_env "xattr cache is not supported"
20898
20899         mkdir -p $DIR/$tdir || error "mkdir failed"
20900         touch $DIR/$tdir/$tfile || error "touch failed"
20901         # OBD_FAIL_LLITE_XATTR_ENOMEM
20902         $LCTL set_param fail_loc=0x1405
20903         getfattr -n user.attr $DIR/$tdir/$tfile &&
20904                 error "getfattr should have failed with ENOMEM"
20905         $LCTL set_param fail_loc=0x0
20906         rm -rf $DIR/$tdir
20907
20908         restore_lustre_params < $p
20909         rm -f $p
20910 }
20911 run_test 234 "xattr cache should not crash on ENOMEM"
20912
20913 test_235() {
20914         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20915                 skip "Need MDS version at least 2.4.52"
20916
20917         flock_deadlock $DIR/$tfile
20918         local RC=$?
20919         case $RC in
20920                 0)
20921                 ;;
20922                 124) error "process hangs on a deadlock"
20923                 ;;
20924                 *) error "error executing flock_deadlock $DIR/$tfile"
20925                 ;;
20926         esac
20927 }
20928 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20929
20930 #LU-2935
20931 test_236() {
20932         check_swap_layouts_support
20933
20934         local ref1=/etc/passwd
20935         local ref2=/etc/group
20936         local file1=$DIR/$tdir/f1
20937         local file2=$DIR/$tdir/f2
20938
20939         test_mkdir -c1 $DIR/$tdir
20940         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20941         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20942         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20943         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20944         local fd=$(free_fd)
20945         local cmd="exec $fd<>$file2"
20946         eval $cmd
20947         rm $file2
20948         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20949                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20950         cmd="exec $fd>&-"
20951         eval $cmd
20952         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20953
20954         #cleanup
20955         rm -rf $DIR/$tdir
20956 }
20957 run_test 236 "Layout swap on open unlinked file"
20958
20959 # LU-4659 linkea consistency
20960 test_238() {
20961         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20962                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20963                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20964                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20965
20966         touch $DIR/$tfile
20967         ln $DIR/$tfile $DIR/$tfile.lnk
20968         touch $DIR/$tfile.new
20969         mv $DIR/$tfile.new $DIR/$tfile
20970         local fid1=$($LFS path2fid $DIR/$tfile)
20971         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20972         local path1=$($LFS fid2path $FSNAME "$fid1")
20973         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20974         local path2=$($LFS fid2path $FSNAME "$fid2")
20975         [ $tfile.lnk == $path2 ] ||
20976                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20977         rm -f $DIR/$tfile*
20978 }
20979 run_test 238 "Verify linkea consistency"
20980
20981 test_239A() { # was test_239
20982         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20983                 skip "Need MDS version at least 2.5.60"
20984
20985         local list=$(comma_list $(mdts_nodes))
20986
20987         mkdir -p $DIR/$tdir
20988         createmany -o $DIR/$tdir/f- 5000
20989         unlinkmany $DIR/$tdir/f- 5000
20990         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20991                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20992         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20993                         osp.*MDT*.sync_in_flight" | calc_sum)
20994         [ "$changes" -eq 0 ] || error "$changes not synced"
20995 }
20996 run_test 239A "osp_sync test"
20997
20998 test_239a() { #LU-5297
20999         remote_mds_nodsh && skip "remote MDS with nodsh"
21000
21001         touch $DIR/$tfile
21002         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21003         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21004         chgrp $RUNAS_GID $DIR/$tfile
21005         wait_delete_completed
21006 }
21007 run_test 239a "process invalid osp sync record correctly"
21008
21009 test_239b() { #LU-5297
21010         remote_mds_nodsh && skip "remote MDS with nodsh"
21011
21012         touch $DIR/$tfile1
21013         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21014         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21015         chgrp $RUNAS_GID $DIR/$tfile1
21016         wait_delete_completed
21017         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21018         touch $DIR/$tfile2
21019         chgrp $RUNAS_GID $DIR/$tfile2
21020         wait_delete_completed
21021 }
21022 run_test 239b "process osp sync record with ENOMEM error correctly"
21023
21024 test_240() {
21025         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21026         remote_mds_nodsh && skip "remote MDS with nodsh"
21027
21028         mkdir -p $DIR/$tdir
21029
21030         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21031                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21032         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21033                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21034
21035         umount_client $MOUNT || error "umount failed"
21036         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21037         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21038         mount_client $MOUNT || error "failed to mount client"
21039
21040         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21041         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21042 }
21043 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21044
21045 test_241_bio() {
21046         local count=$1
21047         local bsize=$2
21048
21049         for LOOP in $(seq $count); do
21050                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21051                 cancel_lru_locks $OSC || true
21052         done
21053 }
21054
21055 test_241_dio() {
21056         local count=$1
21057         local bsize=$2
21058
21059         for LOOP in $(seq $1); do
21060                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21061                         2>/dev/null
21062         done
21063 }
21064
21065 test_241a() { # was test_241
21066         local bsize=$PAGE_SIZE
21067
21068         (( bsize < 40960 )) && bsize=40960
21069         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21070         ls -la $DIR/$tfile
21071         cancel_lru_locks $OSC
21072         test_241_bio 1000 $bsize &
21073         PID=$!
21074         test_241_dio 1000 $bsize
21075         wait $PID
21076 }
21077 run_test 241a "bio vs dio"
21078
21079 test_241b() {
21080         local bsize=$PAGE_SIZE
21081
21082         (( bsize < 40960 )) && bsize=40960
21083         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21084         ls -la $DIR/$tfile
21085         test_241_dio 1000 $bsize &
21086         PID=$!
21087         test_241_dio 1000 $bsize
21088         wait $PID
21089 }
21090 run_test 241b "dio vs dio"
21091
21092 test_242() {
21093         remote_mds_nodsh && skip "remote MDS with nodsh"
21094
21095         mkdir_on_mdt0 $DIR/$tdir
21096         touch $DIR/$tdir/$tfile
21097
21098         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21099         do_facet mds1 lctl set_param fail_loc=0x105
21100         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21101
21102         do_facet mds1 lctl set_param fail_loc=0
21103         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21104 }
21105 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21106
21107 test_243()
21108 {
21109         test_mkdir $DIR/$tdir
21110         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21111 }
21112 run_test 243 "various group lock tests"
21113
21114 test_244a()
21115 {
21116         test_mkdir $DIR/$tdir
21117         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21118         sendfile_grouplock $DIR/$tdir/$tfile || \
21119                 error "sendfile+grouplock failed"
21120         rm -rf $DIR/$tdir
21121 }
21122 run_test 244a "sendfile with group lock tests"
21123
21124 test_244b()
21125 {
21126         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21127
21128         local threads=50
21129         local size=$((1024*1024))
21130
21131         test_mkdir $DIR/$tdir
21132         for i in $(seq 1 $threads); do
21133                 local file=$DIR/$tdir/file_$((i / 10))
21134                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21135                 local pids[$i]=$!
21136         done
21137         for i in $(seq 1 $threads); do
21138                 wait ${pids[$i]}
21139         done
21140 }
21141 run_test 244b "multi-threaded write with group lock"
21142
21143 test_245a() {
21144         local flagname="multi_mod_rpcs"
21145         local connect_data_name="max_mod_rpcs"
21146         local out
21147
21148         # check if multiple modify RPCs flag is set
21149         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21150                 grep "connect_flags:")
21151         echo "$out"
21152
21153         echo "$out" | grep -qw $flagname
21154         if [ $? -ne 0 ]; then
21155                 echo "connect flag $flagname is not set"
21156                 return
21157         fi
21158
21159         # check if multiple modify RPCs data is set
21160         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21161         echo "$out"
21162
21163         echo "$out" | grep -qw $connect_data_name ||
21164                 error "import should have connect data $connect_data_name"
21165 }
21166 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21167
21168 test_245b() {
21169         local flagname="multi_mod_rpcs"
21170         local connect_data_name="max_mod_rpcs"
21171         local out
21172
21173         remote_mds_nodsh && skip "remote MDS with nodsh"
21174         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21175
21176         # check if multiple modify RPCs flag is set
21177         out=$(do_facet mds1 \
21178               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21179               grep "connect_flags:")
21180         echo "$out"
21181
21182         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21183
21184         # check if multiple modify RPCs data is set
21185         out=$(do_facet mds1 \
21186               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21187
21188         [[ "$out" =~ $connect_data_name ]] ||
21189                 {
21190                         echo "$out"
21191                         error "missing connect data $connect_data_name"
21192                 }
21193 }
21194 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21195
21196 cleanup_247() {
21197         local submount=$1
21198
21199         trap 0
21200         umount_client $submount
21201         rmdir $submount
21202 }
21203
21204 test_247a() {
21205         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21206                 grep -q subtree ||
21207                 skip_env "Fileset feature is not supported"
21208
21209         local submount=${MOUNT}_$tdir
21210
21211         mkdir $MOUNT/$tdir
21212         mkdir -p $submount || error "mkdir $submount failed"
21213         FILESET="$FILESET/$tdir" mount_client $submount ||
21214                 error "mount $submount failed"
21215         trap "cleanup_247 $submount" EXIT
21216         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21217         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21218                 error "read $MOUNT/$tdir/$tfile failed"
21219         cleanup_247 $submount
21220 }
21221 run_test 247a "mount subdir as fileset"
21222
21223 test_247b() {
21224         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21225                 skip_env "Fileset feature is not supported"
21226
21227         local submount=${MOUNT}_$tdir
21228
21229         rm -rf $MOUNT/$tdir
21230         mkdir -p $submount || error "mkdir $submount failed"
21231         SKIP_FILESET=1
21232         FILESET="$FILESET/$tdir" mount_client $submount &&
21233                 error "mount $submount should fail"
21234         rmdir $submount
21235 }
21236 run_test 247b "mount subdir that dose not exist"
21237
21238 test_247c() {
21239         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21240                 skip_env "Fileset feature is not supported"
21241
21242         local submount=${MOUNT}_$tdir
21243
21244         mkdir -p $MOUNT/$tdir/dir1
21245         mkdir -p $submount || error "mkdir $submount failed"
21246         trap "cleanup_247 $submount" EXIT
21247         FILESET="$FILESET/$tdir" mount_client $submount ||
21248                 error "mount $submount failed"
21249         local fid=$($LFS path2fid $MOUNT/)
21250         $LFS fid2path $submount $fid && error "fid2path should fail"
21251         cleanup_247 $submount
21252 }
21253 run_test 247c "running fid2path outside subdirectory root"
21254
21255 test_247d() {
21256         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21257                 skip "Fileset feature is not supported"
21258
21259         local submount=${MOUNT}_$tdir
21260
21261         mkdir -p $MOUNT/$tdir/dir1
21262         mkdir -p $submount || error "mkdir $submount failed"
21263         FILESET="$FILESET/$tdir" mount_client $submount ||
21264                 error "mount $submount failed"
21265         trap "cleanup_247 $submount" EXIT
21266
21267         local td=$submount/dir1
21268         local fid=$($LFS path2fid $td)
21269         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21270
21271         # check that we get the same pathname back
21272         local rootpath
21273         local found
21274         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21275                 echo "$rootpath $fid"
21276                 found=$($LFS fid2path $rootpath "$fid")
21277                 [ -n "$found" ] || error "fid2path should succeed"
21278                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21279         done
21280         # check wrong root path format
21281         rootpath=$submount"_wrong"
21282         found=$($LFS fid2path $rootpath "$fid")
21283         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21284
21285         cleanup_247 $submount
21286 }
21287 run_test 247d "running fid2path inside subdirectory root"
21288
21289 # LU-8037
21290 test_247e() {
21291         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21292                 grep -q subtree ||
21293                 skip "Fileset feature is not supported"
21294
21295         local submount=${MOUNT}_$tdir
21296
21297         mkdir $MOUNT/$tdir
21298         mkdir -p $submount || error "mkdir $submount failed"
21299         FILESET="$FILESET/.." mount_client $submount &&
21300                 error "mount $submount should fail"
21301         rmdir $submount
21302 }
21303 run_test 247e "mount .. as fileset"
21304
21305 test_247f() {
21306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21307         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21308                 skip "Need at least version 2.13.52"
21309         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21310                 skip "Need at least version 2.14.50"
21311         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21312                 grep -q subtree ||
21313                 skip "Fileset feature is not supported"
21314
21315         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21316         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21317                 error "mkdir remote failed"
21318         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21319                 error "mkdir remote/subdir failed"
21320         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21321                 error "mkdir striped failed"
21322         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21323
21324         local submount=${MOUNT}_$tdir
21325
21326         mkdir -p $submount || error "mkdir $submount failed"
21327         stack_trap "rmdir $submount"
21328
21329         local dir
21330         local stat
21331         local fileset=$FILESET
21332         local mdts=$(comma_list $(mdts_nodes))
21333
21334         stat=$(do_facet mds1 $LCTL get_param -n \
21335                 mdt.*MDT0000.enable_remote_subdir_mount)
21336         stack_trap "do_nodes $mdts $LCTL set_param \
21337                 mdt.*.enable_remote_subdir_mount=$stat"
21338
21339         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21340         stack_trap "umount_client $submount"
21341         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21342                 error "mount remote dir $dir should fail"
21343
21344         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21345                 $tdir/striped/. ; do
21346                 FILESET="$fileset/$dir" mount_client $submount ||
21347                         error "mount $dir failed"
21348                 umount_client $submount
21349         done
21350
21351         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21352         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21353                 error "mount $tdir/remote failed"
21354 }
21355 run_test 247f "mount striped or remote directory as fileset"
21356
21357 test_247g() {
21358         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21359         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21360                 skip "Need at least version 2.14.50"
21361
21362         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21363                 error "mkdir $tdir failed"
21364         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21365
21366         local submount=${MOUNT}_$tdir
21367
21368         mkdir -p $submount || error "mkdir $submount failed"
21369         stack_trap "rmdir $submount"
21370
21371         FILESET="$fileset/$tdir" mount_client $submount ||
21372                 error "mount $dir failed"
21373         stack_trap "umount $submount"
21374
21375         local mdts=$(comma_list $(mdts_nodes))
21376
21377         local nrpcs
21378
21379         stat $submount > /dev/null
21380         cancel_lru_locks $MDC
21381         stat $submount > /dev/null
21382         stat $submount/$tfile > /dev/null
21383         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21384         stat $submount/$tfile > /dev/null
21385         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21386                 awk '/getattr/ {sum += $2} END {print sum}')
21387
21388         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21389 }
21390 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21391
21392 test_248a() {
21393         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21394         [ -z "$fast_read_sav" ] && skip "no fast read support"
21395
21396         # create a large file for fast read verification
21397         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21398
21399         # make sure the file is created correctly
21400         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21401                 { rm -f $DIR/$tfile; skip "file creation error"; }
21402
21403         echo "Test 1: verify that fast read is 4 times faster on cache read"
21404
21405         # small read with fast read enabled
21406         $LCTL set_param -n llite.*.fast_read=1
21407         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21408                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21409                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21410         # small read with fast read disabled
21411         $LCTL set_param -n llite.*.fast_read=0
21412         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21413                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21414                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21415
21416         # verify that fast read is 4 times faster for cache read
21417         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21418                 error_not_in_vm "fast read was not 4 times faster: " \
21419                            "$t_fast vs $t_slow"
21420
21421         echo "Test 2: verify the performance between big and small read"
21422         $LCTL set_param -n llite.*.fast_read=1
21423
21424         # 1k non-cache read
21425         cancel_lru_locks osc
21426         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21427                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21428                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21429
21430         # 1M non-cache read
21431         cancel_lru_locks osc
21432         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21433                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21434                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21435
21436         # verify that big IO is not 4 times faster than small IO
21437         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21438                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21439
21440         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21441         rm -f $DIR/$tfile
21442 }
21443 run_test 248a "fast read verification"
21444
21445 test_248b() {
21446         # Default short_io_bytes=16384, try both smaller and larger sizes.
21447         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21448         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21449         echo "bs=53248 count=113 normal buffered write"
21450         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21451                 error "dd of initial data file failed"
21452         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21453
21454         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21455         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21456                 error "dd with sync normal writes failed"
21457         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21458
21459         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21460         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21461                 error "dd with sync small writes failed"
21462         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21463
21464         cancel_lru_locks osc
21465
21466         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21467         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21468         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21469         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21470                 iflag=direct || error "dd with O_DIRECT small read failed"
21471         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21472         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21473                 error "compare $TMP/$tfile.1 failed"
21474
21475         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21476         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21477
21478         # just to see what the maximum tunable value is, and test parsing
21479         echo "test invalid parameter 2MB"
21480         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21481                 error "too-large short_io_bytes allowed"
21482         echo "test maximum parameter 512KB"
21483         # if we can set a larger short_io_bytes, run test regardless of version
21484         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21485                 # older clients may not allow setting it this large, that's OK
21486                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21487                         skip "Need at least client version 2.13.50"
21488                 error "medium short_io_bytes failed"
21489         fi
21490         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21491         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21492
21493         echo "test large parameter 64KB"
21494         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21495         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21496
21497         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21498         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21499                 error "dd with sync large writes failed"
21500         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21501
21502         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21503         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21504         num=$((113 * 4096 / PAGE_SIZE))
21505         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21506         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21507                 error "dd with O_DIRECT large writes failed"
21508         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21509                 error "compare $DIR/$tfile.3 failed"
21510
21511         cancel_lru_locks osc
21512
21513         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21514         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21515                 error "dd with O_DIRECT large read failed"
21516         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21517                 error "compare $TMP/$tfile.2 failed"
21518
21519         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21520         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21521                 error "dd with O_DIRECT large read failed"
21522         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21523                 error "compare $TMP/$tfile.3 failed"
21524 }
21525 run_test 248b "test short_io read and write for both small and large sizes"
21526
21527 test_249() { # LU-7890
21528         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21529                 skip "Need at least version 2.8.54"
21530
21531         rm -f $DIR/$tfile
21532         $LFS setstripe -c 1 $DIR/$tfile
21533         # Offset 2T == 4k * 512M
21534         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21535                 error "dd to 2T offset failed"
21536 }
21537 run_test 249 "Write above 2T file size"
21538
21539 test_250() {
21540         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21541          && skip "no 16TB file size limit on ZFS"
21542
21543         $LFS setstripe -c 1 $DIR/$tfile
21544         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21545         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21546         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21547         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21548                 conv=notrunc,fsync && error "append succeeded"
21549         return 0
21550 }
21551 run_test 250 "Write above 16T limit"
21552
21553 test_251() {
21554         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21555
21556         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21557         #Skip once - writing the first stripe will succeed
21558         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21559         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21560                 error "short write happened"
21561
21562         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21563         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21564                 error "short read happened"
21565
21566         rm -f $DIR/$tfile
21567 }
21568 run_test 251 "Handling short read and write correctly"
21569
21570 test_252() {
21571         remote_mds_nodsh && skip "remote MDS with nodsh"
21572         remote_ost_nodsh && skip "remote OST with nodsh"
21573         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21574                 skip_env "ldiskfs only test"
21575         fi
21576
21577         local tgt
21578         local dev
21579         local out
21580         local uuid
21581         local num
21582         local gen
21583
21584         # check lr_reader on OST0000
21585         tgt=ost1
21586         dev=$(facet_device $tgt)
21587         out=$(do_facet $tgt $LR_READER $dev)
21588         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21589         echo "$out"
21590         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21591         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21592                 error "Invalid uuid returned by $LR_READER on target $tgt"
21593         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21594
21595         # check lr_reader -c on MDT0000
21596         tgt=mds1
21597         dev=$(facet_device $tgt)
21598         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21599                 skip "$LR_READER does not support additional options"
21600         fi
21601         out=$(do_facet $tgt $LR_READER -c $dev)
21602         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21603         echo "$out"
21604         num=$(echo "$out" | grep -c "mdtlov")
21605         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21606                 error "Invalid number of mdtlov clients returned by $LR_READER"
21607         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21608
21609         # check lr_reader -cr on MDT0000
21610         out=$(do_facet $tgt $LR_READER -cr $dev)
21611         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21612         echo "$out"
21613         echo "$out" | grep -q "^reply_data:$" ||
21614                 error "$LR_READER should have returned 'reply_data' section"
21615         num=$(echo "$out" | grep -c "client_generation")
21616         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21617 }
21618 run_test 252 "check lr_reader tool"
21619
21620 test_253() {
21621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21622         remote_mds_nodsh && skip "remote MDS with nodsh"
21623         remote_mgs_nodsh && skip "remote MGS with nodsh"
21624
21625         local ostidx=0
21626         local rc=0
21627         local ost_name=$(ostname_from_index $ostidx)
21628
21629         # on the mdt's osc
21630         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21631         do_facet $SINGLEMDS $LCTL get_param -n \
21632                 osp.$mdtosc_proc1.reserved_mb_high ||
21633                 skip  "remote MDS does not support reserved_mb_high"
21634
21635         rm -rf $DIR/$tdir
21636         wait_mds_ost_sync
21637         wait_delete_completed
21638         mkdir $DIR/$tdir
21639
21640         pool_add $TESTNAME || error "Pool creation failed"
21641         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21642
21643         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21644                 error "Setstripe failed"
21645
21646         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21647
21648         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21649                     grep "watermarks")
21650         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21651
21652         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21653                         osp.$mdtosc_proc1.prealloc_status)
21654         echo "prealloc_status $oa_status"
21655
21656         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21657                 error "File creation should fail"
21658
21659         #object allocation was stopped, but we still able to append files
21660         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21661                 oflag=append || error "Append failed"
21662
21663         rm -f $DIR/$tdir/$tfile.0
21664
21665         # For this test, we want to delete the files we created to go out of
21666         # space but leave the watermark, so we remain nearly out of space
21667         ost_watermarks_enospc_delete_files $tfile $ostidx
21668
21669         wait_delete_completed
21670
21671         sleep_maxage
21672
21673         for i in $(seq 10 12); do
21674                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21675                         2>/dev/null || error "File creation failed after rm"
21676         done
21677
21678         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21679                         osp.$mdtosc_proc1.prealloc_status)
21680         echo "prealloc_status $oa_status"
21681
21682         if (( oa_status != 0 )); then
21683                 error "Object allocation still disable after rm"
21684         fi
21685 }
21686 run_test 253 "Check object allocation limit"
21687
21688 test_254() {
21689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21690         remote_mds_nodsh && skip "remote MDS with nodsh"
21691
21692         local mdt=$(facet_svc $SINGLEMDS)
21693
21694         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21695                 skip "MDS does not support changelog_size"
21696
21697         local cl_user
21698
21699         changelog_register || error "changelog_register failed"
21700
21701         changelog_clear 0 || error "changelog_clear failed"
21702
21703         local size1=$(do_facet $SINGLEMDS \
21704                       $LCTL get_param -n mdd.$mdt.changelog_size)
21705         echo "Changelog size $size1"
21706
21707         rm -rf $DIR/$tdir
21708         $LFS mkdir -i 0 $DIR/$tdir
21709         # change something
21710         mkdir -p $DIR/$tdir/pics/2008/zachy
21711         touch $DIR/$tdir/pics/2008/zachy/timestamp
21712         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21713         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21714         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21715         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21716         rm $DIR/$tdir/pics/desktop.jpg
21717
21718         local size2=$(do_facet $SINGLEMDS \
21719                       $LCTL get_param -n mdd.$mdt.changelog_size)
21720         echo "Changelog size after work $size2"
21721
21722         (( $size2 > $size1 )) ||
21723                 error "new Changelog size=$size2 less than old size=$size1"
21724 }
21725 run_test 254 "Check changelog size"
21726
21727 ladvise_no_type()
21728 {
21729         local type=$1
21730         local file=$2
21731
21732         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21733                 awk -F: '{print $2}' | grep $type > /dev/null
21734         if [ $? -ne 0 ]; then
21735                 return 0
21736         fi
21737         return 1
21738 }
21739
21740 ladvise_no_ioctl()
21741 {
21742         local file=$1
21743
21744         lfs ladvise -a willread $file > /dev/null 2>&1
21745         if [ $? -eq 0 ]; then
21746                 return 1
21747         fi
21748
21749         lfs ladvise -a willread $file 2>&1 |
21750                 grep "Inappropriate ioctl for device" > /dev/null
21751         if [ $? -eq 0 ]; then
21752                 return 0
21753         fi
21754         return 1
21755 }
21756
21757 percent() {
21758         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21759 }
21760
21761 # run a random read IO workload
21762 # usage: random_read_iops <filename> <filesize> <iosize>
21763 random_read_iops() {
21764         local file=$1
21765         local fsize=$2
21766         local iosize=${3:-4096}
21767
21768         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21769                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21770 }
21771
21772 drop_file_oss_cache() {
21773         local file="$1"
21774         local nodes="$2"
21775
21776         $LFS ladvise -a dontneed $file 2>/dev/null ||
21777                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21778 }
21779
21780 ladvise_willread_performance()
21781 {
21782         local repeat=10
21783         local average_origin=0
21784         local average_cache=0
21785         local average_ladvise=0
21786
21787         for ((i = 1; i <= $repeat; i++)); do
21788                 echo "Iter $i/$repeat: reading without willread hint"
21789                 cancel_lru_locks osc
21790                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21791                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21792                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21793                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21794
21795                 cancel_lru_locks osc
21796                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21797                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21798                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21799
21800                 cancel_lru_locks osc
21801                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21802                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21803                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21804                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21805                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21806         done
21807         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21808         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21809         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21810
21811         speedup_cache=$(percent $average_cache $average_origin)
21812         speedup_ladvise=$(percent $average_ladvise $average_origin)
21813
21814         echo "Average uncached read: $average_origin"
21815         echo "Average speedup with OSS cached read: " \
21816                 "$average_cache = +$speedup_cache%"
21817         echo "Average speedup with ladvise willread: " \
21818                 "$average_ladvise = +$speedup_ladvise%"
21819
21820         local lowest_speedup=20
21821         if (( ${average_cache%.*} < $lowest_speedup )); then
21822                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21823                      " got $average_cache%. Skipping ladvise willread check."
21824                 return 0
21825         fi
21826
21827         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21828         # it is still good to run until then to exercise 'ladvise willread'
21829         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21830                 [ "$ost1_FSTYPE" = "zfs" ] &&
21831                 echo "osd-zfs does not support dontneed or drop_caches" &&
21832                 return 0
21833
21834         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21835         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21836                 error_not_in_vm "Speedup with willread is less than " \
21837                         "$lowest_speedup%, got $average_ladvise%"
21838 }
21839
21840 test_255a() {
21841         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21842                 skip "lustre < 2.8.54 does not support ladvise "
21843         remote_ost_nodsh && skip "remote OST with nodsh"
21844
21845         stack_trap "rm -f $DIR/$tfile"
21846         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21847
21848         ladvise_no_type willread $DIR/$tfile &&
21849                 skip "willread ladvise is not supported"
21850
21851         ladvise_no_ioctl $DIR/$tfile &&
21852                 skip "ladvise ioctl is not supported"
21853
21854         local size_mb=100
21855         local size=$((size_mb * 1048576))
21856         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21857                 error "dd to $DIR/$tfile failed"
21858
21859         lfs ladvise -a willread $DIR/$tfile ||
21860                 error "Ladvise failed with no range argument"
21861
21862         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21863                 error "Ladvise failed with no -l or -e argument"
21864
21865         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21866                 error "Ladvise failed with only -e argument"
21867
21868         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21869                 error "Ladvise failed with only -l argument"
21870
21871         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21872                 error "End offset should not be smaller than start offset"
21873
21874         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21875                 error "End offset should not be equal to start offset"
21876
21877         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21878                 error "Ladvise failed with overflowing -s argument"
21879
21880         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21881                 error "Ladvise failed with overflowing -e argument"
21882
21883         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21884                 error "Ladvise failed with overflowing -l argument"
21885
21886         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21887                 error "Ladvise succeeded with conflicting -l and -e arguments"
21888
21889         echo "Synchronous ladvise should wait"
21890         local delay=4
21891 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21892         do_nodes $(comma_list $(osts_nodes)) \
21893                 $LCTL set_param fail_val=$delay fail_loc=0x237
21894
21895         local start_ts=$SECONDS
21896         lfs ladvise -a willread $DIR/$tfile ||
21897                 error "Ladvise failed with no range argument"
21898         local end_ts=$SECONDS
21899         local inteval_ts=$((end_ts - start_ts))
21900
21901         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21902                 error "Synchronous advice didn't wait reply"
21903         fi
21904
21905         echo "Asynchronous ladvise shouldn't wait"
21906         local start_ts=$SECONDS
21907         lfs ladvise -a willread -b $DIR/$tfile ||
21908                 error "Ladvise failed with no range argument"
21909         local end_ts=$SECONDS
21910         local inteval_ts=$((end_ts - start_ts))
21911
21912         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21913                 error "Asynchronous advice blocked"
21914         fi
21915
21916         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21917         ladvise_willread_performance
21918 }
21919 run_test 255a "check 'lfs ladvise -a willread'"
21920
21921 facet_meminfo() {
21922         local facet=$1
21923         local info=$2
21924
21925         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21926 }
21927
21928 test_255b() {
21929         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21930                 skip "lustre < 2.8.54 does not support ladvise "
21931         remote_ost_nodsh && skip "remote OST with nodsh"
21932
21933         stack_trap "rm -f $DIR/$tfile"
21934         lfs setstripe -c 1 -i 0 $DIR/$tfile
21935
21936         ladvise_no_type dontneed $DIR/$tfile &&
21937                 skip "dontneed ladvise is not supported"
21938
21939         ladvise_no_ioctl $DIR/$tfile &&
21940                 skip "ladvise ioctl is not supported"
21941
21942         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21943                 [ "$ost1_FSTYPE" = "zfs" ] &&
21944                 skip "zfs-osd does not support 'ladvise dontneed'"
21945
21946         local size_mb=100
21947         local size=$((size_mb * 1048576))
21948         # In order to prevent disturbance of other processes, only check 3/4
21949         # of the memory usage
21950         local kibibytes=$((size_mb * 1024 * 3 / 4))
21951
21952         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21953                 error "dd to $DIR/$tfile failed"
21954
21955         #force write to complete before dropping OST cache & checking memory
21956         sync
21957
21958         local total=$(facet_meminfo ost1 MemTotal)
21959         echo "Total memory: $total KiB"
21960
21961         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21962         local before_read=$(facet_meminfo ost1 Cached)
21963         echo "Cache used before read: $before_read KiB"
21964
21965         lfs ladvise -a willread $DIR/$tfile ||
21966                 error "Ladvise willread failed"
21967         local after_read=$(facet_meminfo ost1 Cached)
21968         echo "Cache used after read: $after_read KiB"
21969
21970         lfs ladvise -a dontneed $DIR/$tfile ||
21971                 error "Ladvise dontneed again failed"
21972         local no_read=$(facet_meminfo ost1 Cached)
21973         echo "Cache used after dontneed ladvise: $no_read KiB"
21974
21975         if [ $total -lt $((before_read + kibibytes)) ]; then
21976                 echo "Memory is too small, abort checking"
21977                 return 0
21978         fi
21979
21980         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21981                 error "Ladvise willread should use more memory" \
21982                         "than $kibibytes KiB"
21983         fi
21984
21985         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21986                 error "Ladvise dontneed should release more memory" \
21987                         "than $kibibytes KiB"
21988         fi
21989 }
21990 run_test 255b "check 'lfs ladvise -a dontneed'"
21991
21992 test_255c() {
21993         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21994                 skip "lustre < 2.10.50 does not support lockahead"
21995
21996         local ost1_imp=$(get_osc_import_name client ost1)
21997         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21998                          cut -d'.' -f2)
21999         local count
22000         local new_count
22001         local difference
22002         local i
22003         local rc
22004
22005         test_mkdir -p $DIR/$tdir
22006         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22007
22008         #test 10 returns only success/failure
22009         i=10
22010         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22011         rc=$?
22012         if [ $rc -eq 255 ]; then
22013                 error "Ladvise test${i} failed, ${rc}"
22014         fi
22015
22016         #test 11 counts lock enqueue requests, all others count new locks
22017         i=11
22018         count=$(do_facet ost1 \
22019                 $LCTL get_param -n ost.OSS.ost.stats)
22020         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22021
22022         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22023         rc=$?
22024         if [ $rc -eq 255 ]; then
22025                 error "Ladvise test${i} failed, ${rc}"
22026         fi
22027
22028         new_count=$(do_facet ost1 \
22029                 $LCTL get_param -n ost.OSS.ost.stats)
22030         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22031                    awk '{ print $2 }')
22032
22033         difference="$((new_count - count))"
22034         if [ $difference -ne $rc ]; then
22035                 error "Ladvise test${i}, bad enqueue count, returned " \
22036                       "${rc}, actual ${difference}"
22037         fi
22038
22039         for i in $(seq 12 21); do
22040                 # If we do not do this, we run the risk of having too many
22041                 # locks and starting lock cancellation while we are checking
22042                 # lock counts.
22043                 cancel_lru_locks osc
22044
22045                 count=$($LCTL get_param -n \
22046                        ldlm.namespaces.$imp_name.lock_unused_count)
22047
22048                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22049                 rc=$?
22050                 if [ $rc -eq 255 ]; then
22051                         error "Ladvise test ${i} failed, ${rc}"
22052                 fi
22053
22054                 new_count=$($LCTL get_param -n \
22055                        ldlm.namespaces.$imp_name.lock_unused_count)
22056                 difference="$((new_count - count))"
22057
22058                 # Test 15 output is divided by 100 to map down to valid return
22059                 if [ $i -eq 15 ]; then
22060                         rc="$((rc * 100))"
22061                 fi
22062
22063                 if [ $difference -ne $rc ]; then
22064                         error "Ladvise test ${i}, bad lock count, returned " \
22065                               "${rc}, actual ${difference}"
22066                 fi
22067         done
22068
22069         #test 22 returns only success/failure
22070         i=22
22071         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22072         rc=$?
22073         if [ $rc -eq 255 ]; then
22074                 error "Ladvise test${i} failed, ${rc}"
22075         fi
22076 }
22077 run_test 255c "suite of ladvise lockahead tests"
22078
22079 test_256() {
22080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22081         remote_mds_nodsh && skip "remote MDS with nodsh"
22082         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22083         changelog_users $SINGLEMDS | grep "^cl" &&
22084                 skip "active changelog user"
22085
22086         local cl_user
22087         local cat_sl
22088         local mdt_dev
22089
22090         mdt_dev=$(facet_device $SINGLEMDS)
22091         echo $mdt_dev
22092
22093         changelog_register || error "changelog_register failed"
22094
22095         rm -rf $DIR/$tdir
22096         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22097
22098         changelog_clear 0 || error "changelog_clear failed"
22099
22100         # change something
22101         touch $DIR/$tdir/{1..10}
22102
22103         # stop the MDT
22104         stop $SINGLEMDS || error "Fail to stop MDT"
22105
22106         # remount the MDT
22107         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22108                 error "Fail to start MDT"
22109
22110         #after mount new plainllog is used
22111         touch $DIR/$tdir/{11..19}
22112         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22113         stack_trap "rm -f $tmpfile"
22114         cat_sl=$(do_facet $SINGLEMDS "sync; \
22115                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22116                  llog_reader $tmpfile | grep -c type=1064553b")
22117         do_facet $SINGLEMDS llog_reader $tmpfile
22118
22119         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22120
22121         changelog_clear 0 || error "changelog_clear failed"
22122
22123         cat_sl=$(do_facet $SINGLEMDS "sync; \
22124                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22125                  llog_reader $tmpfile | grep -c type=1064553b")
22126
22127         if (( cat_sl == 2 )); then
22128                 error "Empty plain llog was not deleted from changelog catalog"
22129         elif (( cat_sl != 1 )); then
22130                 error "Active plain llog shouldn't be deleted from catalog"
22131         fi
22132 }
22133 run_test 256 "Check llog delete for empty and not full state"
22134
22135 test_257() {
22136         remote_mds_nodsh && skip "remote MDS with nodsh"
22137         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22138                 skip "Need MDS version at least 2.8.55"
22139
22140         test_mkdir $DIR/$tdir
22141
22142         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22143                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22144         stat $DIR/$tdir
22145
22146 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22147         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22148         local facet=mds$((mdtidx + 1))
22149         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22150         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22151
22152         stop $facet || error "stop MDS failed"
22153         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22154                 error "start MDS fail"
22155         wait_recovery_complete $facet
22156 }
22157 run_test 257 "xattr locks are not lost"
22158
22159 # Verify we take the i_mutex when security requires it
22160 test_258a() {
22161 #define OBD_FAIL_IMUTEX_SEC 0x141c
22162         $LCTL set_param fail_loc=0x141c
22163         touch $DIR/$tfile
22164         chmod u+s $DIR/$tfile
22165         chmod a+rwx $DIR/$tfile
22166         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22167         RC=$?
22168         if [ $RC -ne 0 ]; then
22169                 error "error, failed to take i_mutex, rc=$?"
22170         fi
22171         rm -f $DIR/$tfile
22172 }
22173 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22174
22175 # Verify we do NOT take the i_mutex in the normal case
22176 test_258b() {
22177 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22178         $LCTL set_param fail_loc=0x141d
22179         touch $DIR/$tfile
22180         chmod a+rwx $DIR
22181         chmod a+rw $DIR/$tfile
22182         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22183         RC=$?
22184         if [ $RC -ne 0 ]; then
22185                 error "error, took i_mutex unnecessarily, rc=$?"
22186         fi
22187         rm -f $DIR/$tfile
22188
22189 }
22190 run_test 258b "verify i_mutex security behavior"
22191
22192 test_259() {
22193         local file=$DIR/$tfile
22194         local before
22195         local after
22196
22197         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22198
22199         stack_trap "rm -f $file" EXIT
22200
22201         wait_delete_completed
22202         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22203         echo "before: $before"
22204
22205         $LFS setstripe -i 0 -c 1 $file
22206         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22207         sync_all_data
22208         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22209         echo "after write: $after"
22210
22211 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22212         do_facet ost1 $LCTL set_param fail_loc=0x2301
22213         $TRUNCATE $file 0
22214         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22215         echo "after truncate: $after"
22216
22217         stop ost1
22218         do_facet ost1 $LCTL set_param fail_loc=0
22219         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22220         sleep 2
22221         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22222         echo "after restart: $after"
22223         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22224                 error "missing truncate?"
22225
22226         return 0
22227 }
22228 run_test 259 "crash at delayed truncate"
22229
22230 test_260() {
22231 #define OBD_FAIL_MDC_CLOSE               0x806
22232         $LCTL set_param fail_loc=0x80000806
22233         touch $DIR/$tfile
22234
22235 }
22236 run_test 260 "Check mdc_close fail"
22237
22238 ### Data-on-MDT sanity tests ###
22239 test_270a() {
22240         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22241                 skip "Need MDS version at least 2.10.55 for DoM"
22242
22243         # create DoM file
22244         local dom=$DIR/$tdir/dom_file
22245         local tmp=$DIR/$tdir/tmp_file
22246
22247         mkdir_on_mdt0 $DIR/$tdir
22248
22249         # basic checks for DoM component creation
22250         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22251                 error "Can set MDT layout to non-first entry"
22252
22253         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22254                 error "Can define multiple entries as MDT layout"
22255
22256         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22257
22258         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22259         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22260         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22261
22262         local mdtidx=$($LFS getstripe -m $dom)
22263         local mdtname=MDT$(printf %04x $mdtidx)
22264         local facet=mds$((mdtidx + 1))
22265         local space_check=1
22266
22267         # Skip free space checks with ZFS
22268         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22269
22270         # write
22271         sync
22272         local size_tmp=$((65536 * 3))
22273         local mdtfree1=$(do_facet $facet \
22274                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22275
22276         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22277         # check also direct IO along write
22278         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22279         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22280         sync
22281         cmp $tmp $dom || error "file data is different"
22282         [ $(stat -c%s $dom) == $size_tmp ] ||
22283                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22284         if [ $space_check == 1 ]; then
22285                 local mdtfree2=$(do_facet $facet \
22286                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22287
22288                 # increase in usage from by $size_tmp
22289                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22290                         error "MDT free space wrong after write: " \
22291                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22292         fi
22293
22294         # truncate
22295         local size_dom=10000
22296
22297         $TRUNCATE $dom $size_dom
22298         [ $(stat -c%s $dom) == $size_dom ] ||
22299                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22300         if [ $space_check == 1 ]; then
22301                 mdtfree1=$(do_facet $facet \
22302                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22303                 # decrease in usage from $size_tmp to new $size_dom
22304                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22305                   $(((size_tmp - size_dom) / 1024)) ] ||
22306                         error "MDT free space is wrong after truncate: " \
22307                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22308         fi
22309
22310         # append
22311         cat $tmp >> $dom
22312         sync
22313         size_dom=$((size_dom + size_tmp))
22314         [ $(stat -c%s $dom) == $size_dom ] ||
22315                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22316         if [ $space_check == 1 ]; then
22317                 mdtfree2=$(do_facet $facet \
22318                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22319                 # increase in usage by $size_tmp from previous
22320                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22321                         error "MDT free space is wrong after append: " \
22322                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22323         fi
22324
22325         # delete
22326         rm $dom
22327         if [ $space_check == 1 ]; then
22328                 mdtfree1=$(do_facet $facet \
22329                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22330                 # decrease in usage by $size_dom from previous
22331                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22332                         error "MDT free space is wrong after removal: " \
22333                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22334         fi
22335
22336         # combined striping
22337         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22338                 error "Can't create DoM + OST striping"
22339
22340         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22341         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22342         # check also direct IO along write
22343         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22344         sync
22345         cmp $tmp $dom || error "file data is different"
22346         [ $(stat -c%s $dom) == $size_tmp ] ||
22347                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22348         rm $dom $tmp
22349
22350         return 0
22351 }
22352 run_test 270a "DoM: basic functionality tests"
22353
22354 test_270b() {
22355         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22356                 skip "Need MDS version at least 2.10.55"
22357
22358         local dom=$DIR/$tdir/dom_file
22359         local max_size=1048576
22360
22361         mkdir -p $DIR/$tdir
22362         $LFS setstripe -E $max_size -L mdt $dom
22363
22364         # truncate over the limit
22365         $TRUNCATE $dom $(($max_size + 1)) &&
22366                 error "successful truncate over the maximum size"
22367         # write over the limit
22368         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22369                 error "successful write over the maximum size"
22370         # append over the limit
22371         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22372         echo "12345" >> $dom && error "successful append over the maximum size"
22373         rm $dom
22374
22375         return 0
22376 }
22377 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22378
22379 test_270c() {
22380         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22381                 skip "Need MDS version at least 2.10.55"
22382
22383         mkdir -p $DIR/$tdir
22384         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22385
22386         # check files inherit DoM EA
22387         touch $DIR/$tdir/first
22388         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22389                 error "bad pattern"
22390         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22391                 error "bad stripe count"
22392         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22393                 error "bad stripe size"
22394
22395         # check directory inherits DoM EA and uses it as default
22396         mkdir $DIR/$tdir/subdir
22397         touch $DIR/$tdir/subdir/second
22398         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22399                 error "bad pattern in sub-directory"
22400         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22401                 error "bad stripe count in sub-directory"
22402         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22403                 error "bad stripe size in sub-directory"
22404         return 0
22405 }
22406 run_test 270c "DoM: DoM EA inheritance tests"
22407
22408 test_270d() {
22409         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22410                 skip "Need MDS version at least 2.10.55"
22411
22412         mkdir -p $DIR/$tdir
22413         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22414
22415         # inherit default DoM striping
22416         mkdir $DIR/$tdir/subdir
22417         touch $DIR/$tdir/subdir/f1
22418
22419         # change default directory striping
22420         $LFS setstripe -c 1 $DIR/$tdir/subdir
22421         touch $DIR/$tdir/subdir/f2
22422         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22423                 error "wrong default striping in file 2"
22424         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22425                 error "bad pattern in file 2"
22426         return 0
22427 }
22428 run_test 270d "DoM: change striping from DoM to RAID0"
22429
22430 test_270e() {
22431         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22432                 skip "Need MDS version at least 2.10.55"
22433
22434         mkdir -p $DIR/$tdir/dom
22435         mkdir -p $DIR/$tdir/norm
22436         DOMFILES=20
22437         NORMFILES=10
22438         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22439         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22440
22441         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22442         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22443
22444         # find DoM files by layout
22445         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22446         [ $NUM -eq  $DOMFILES ] ||
22447                 error "lfs find -L: found $NUM, expected $DOMFILES"
22448         echo "Test 1: lfs find 20 DOM files by layout: OK"
22449
22450         # there should be 1 dir with default DOM striping
22451         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22452         [ $NUM -eq  1 ] ||
22453                 error "lfs find -L: found $NUM, expected 1 dir"
22454         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22455
22456         # find DoM files by stripe size
22457         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22458         [ $NUM -eq  $DOMFILES ] ||
22459                 error "lfs find -S: found $NUM, expected $DOMFILES"
22460         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22461
22462         # find files by stripe offset except DoM files
22463         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22464         [ $NUM -eq  $NORMFILES ] ||
22465                 error "lfs find -i: found $NUM, expected $NORMFILES"
22466         echo "Test 5: lfs find no DOM files by stripe index: OK"
22467         return 0
22468 }
22469 run_test 270e "DoM: lfs find with DoM files test"
22470
22471 test_270f() {
22472         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22473                 skip "Need MDS version at least 2.10.55"
22474
22475         local mdtname=${FSNAME}-MDT0000-mdtlov
22476         local dom=$DIR/$tdir/dom_file
22477         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22478                                                 lod.$mdtname.dom_stripesize)
22479         local dom_limit=131072
22480
22481         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22482         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22483                                                 lod.$mdtname.dom_stripesize)
22484         [ ${dom_limit} -eq ${dom_current} ] ||
22485                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22486
22487         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22488         $LFS setstripe -d $DIR/$tdir
22489         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22490                 error "Can't set directory default striping"
22491
22492         # exceed maximum stripe size
22493         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22494                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22495         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22496                 error "Able to create DoM component size more than LOD limit"
22497
22498         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22499         dom_current=$(do_facet mds1 $LCTL get_param -n \
22500                                                 lod.$mdtname.dom_stripesize)
22501         [ 0 -eq ${dom_current} ] ||
22502                 error "Can't set zero DoM stripe limit"
22503         rm $dom
22504
22505         # attempt to create DoM file on server with disabled DoM should
22506         # remove DoM entry from layout and be succeed
22507         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22508                 error "Can't create DoM file (DoM is disabled)"
22509         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22510                 error "File has DoM component while DoM is disabled"
22511         rm $dom
22512
22513         # attempt to create DoM file with only DoM stripe should return error
22514         $LFS setstripe -E $dom_limit -L mdt $dom &&
22515                 error "Able to create DoM-only file while DoM is disabled"
22516
22517         # too low values to be aligned with smallest stripe size 64K
22518         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22519         dom_current=$(do_facet mds1 $LCTL get_param -n \
22520                                                 lod.$mdtname.dom_stripesize)
22521         [ 30000 -eq ${dom_current} ] &&
22522                 error "Can set too small DoM stripe limit"
22523
22524         # 64K is a minimal stripe size in Lustre, expect limit of that size
22525         [ 65536 -eq ${dom_current} ] ||
22526                 error "Limit is not set to 64K but ${dom_current}"
22527
22528         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22529         dom_current=$(do_facet mds1 $LCTL get_param -n \
22530                                                 lod.$mdtname.dom_stripesize)
22531         echo $dom_current
22532         [ 2147483648 -eq ${dom_current} ] &&
22533                 error "Can set too large DoM stripe limit"
22534
22535         do_facet mds1 $LCTL set_param -n \
22536                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22537         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22538                 error "Can't create DoM component size after limit change"
22539         do_facet mds1 $LCTL set_param -n \
22540                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22541         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22542                 error "Can't create DoM file after limit decrease"
22543         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22544                 error "Can create big DoM component after limit decrease"
22545         touch ${dom}_def ||
22546                 error "Can't create file with old default layout"
22547
22548         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22549         return 0
22550 }
22551 run_test 270f "DoM: maximum DoM stripe size checks"
22552
22553 test_270g() {
22554         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22555                 skip "Need MDS version at least 2.13.52"
22556         local dom=$DIR/$tdir/$tfile
22557
22558         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22559         local lodname=${FSNAME}-MDT0000-mdtlov
22560
22561         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22562         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22563         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22564         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22565
22566         local dom_limit=1024
22567         local dom_threshold="50%"
22568
22569         $LFS setstripe -d $DIR/$tdir
22570         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22571                 error "Can't set directory default striping"
22572
22573         do_facet mds1 $LCTL set_param -n \
22574                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22575         # set 0 threshold and create DOM file to change tunable stripesize
22576         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22577         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22578                 error "Failed to create $dom file"
22579         # now tunable dom_cur_stripesize should reach maximum
22580         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22581                                         lod.${lodname}.dom_stripesize_cur_kb)
22582         [[ $dom_current == $dom_limit ]] ||
22583                 error "Current DOM stripesize is not maximum"
22584         rm $dom
22585
22586         # set threshold for further tests
22587         do_facet mds1 $LCTL set_param -n \
22588                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22589         echo "DOM threshold is $dom_threshold free space"
22590         local dom_def
22591         local dom_set
22592         # Spoof bfree to exceed threshold
22593         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22594         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22595         for spfree in 40 20 0 15 30 55; do
22596                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22597                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22598                         error "Failed to create $dom file"
22599                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22600                                         lod.${lodname}.dom_stripesize_cur_kb)
22601                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22602                 [[ $dom_def != $dom_current ]] ||
22603                         error "Default stripe size was not changed"
22604                 if (( spfree > 0 )) ; then
22605                         dom_set=$($LFS getstripe -S $dom)
22606                         (( dom_set == dom_def * 1024 )) ||
22607                                 error "DOM component size is still old"
22608                 else
22609                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22610                                 error "DoM component is set with no free space"
22611                 fi
22612                 rm $dom
22613                 dom_current=$dom_def
22614         done
22615 }
22616 run_test 270g "DoM: default DoM stripe size depends on free space"
22617
22618 test_270h() {
22619         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22620                 skip "Need MDS version at least 2.13.53"
22621
22622         local mdtname=${FSNAME}-MDT0000-mdtlov
22623         local dom=$DIR/$tdir/$tfile
22624         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22625
22626         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22627         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22628
22629         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22630         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22631                 error "can't create OST file"
22632         # mirrored file with DOM entry in the second mirror
22633         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22634                 error "can't create mirror with DoM component"
22635
22636         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22637
22638         # DOM component in the middle and has other enries in the same mirror,
22639         # should succeed but lost DoM component
22640         $LFS setstripe --copy=${dom}_1 $dom ||
22641                 error "Can't create file from OST|DOM mirror layout"
22642         # check new file has no DoM layout after all
22643         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22644                 error "File has DoM component while DoM is disabled"
22645 }
22646 run_test 270h "DoM: DoM stripe removal when disabled on server"
22647
22648 test_270i() {
22649         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22650                 skip "Need MDS version at least 2.14.54"
22651
22652         mkdir $DIR/$tdir
22653         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22654                 error "setstripe should fail" || true
22655 }
22656 run_test 270i "DoM: setting invalid DoM striping should fail"
22657
22658 test_271a() {
22659         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22660                 skip "Need MDS version at least 2.10.55"
22661
22662         local dom=$DIR/$tdir/dom
22663
22664         mkdir -p $DIR/$tdir
22665
22666         $LFS setstripe -E 1024K -L mdt $dom
22667
22668         lctl set_param -n mdc.*.stats=clear
22669         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22670         cat $dom > /dev/null
22671         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22672         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22673         ls $dom
22674         rm -f $dom
22675 }
22676 run_test 271a "DoM: data is cached for read after write"
22677
22678 test_271b() {
22679         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22680                 skip "Need MDS version at least 2.10.55"
22681
22682         local dom=$DIR/$tdir/dom
22683
22684         mkdir -p $DIR/$tdir
22685
22686         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22687
22688         lctl set_param -n mdc.*.stats=clear
22689         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22690         cancel_lru_locks mdc
22691         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22692         # second stat to check size is cached on client
22693         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22694         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22695         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22696         rm -f $dom
22697 }
22698 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22699
22700 test_271ba() {
22701         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22702                 skip "Need MDS version at least 2.10.55"
22703
22704         local dom=$DIR/$tdir/dom
22705
22706         mkdir -p $DIR/$tdir
22707
22708         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22709
22710         lctl set_param -n mdc.*.stats=clear
22711         lctl set_param -n osc.*.stats=clear
22712         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22713         cancel_lru_locks mdc
22714         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22715         # second stat to check size is cached on client
22716         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22717         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22718         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22719         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22720         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22721         rm -f $dom
22722 }
22723 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22724
22725
22726 get_mdc_stats() {
22727         local mdtidx=$1
22728         local param=$2
22729         local mdt=MDT$(printf %04x $mdtidx)
22730
22731         if [ -z $param ]; then
22732                 lctl get_param -n mdc.*$mdt*.stats
22733         else
22734                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22735         fi
22736 }
22737
22738 test_271c() {
22739         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22740                 skip "Need MDS version at least 2.10.55"
22741
22742         local dom=$DIR/$tdir/dom
22743
22744         mkdir -p $DIR/$tdir
22745
22746         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22747
22748         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22749         local facet=mds$((mdtidx + 1))
22750
22751         cancel_lru_locks mdc
22752         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22753         createmany -o $dom 1000
22754         lctl set_param -n mdc.*.stats=clear
22755         smalliomany -w $dom 1000 200
22756         get_mdc_stats $mdtidx
22757         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22758         # Each file has 1 open, 1 IO enqueues, total 2000
22759         # but now we have also +1 getxattr for security.capability, total 3000
22760         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22761         unlinkmany $dom 1000
22762
22763         cancel_lru_locks mdc
22764         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22765         createmany -o $dom 1000
22766         lctl set_param -n mdc.*.stats=clear
22767         smalliomany -w $dom 1000 200
22768         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22769         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22770         # for OPEN and IO lock.
22771         [ $((enq - enq_2)) -ge 1000 ] ||
22772                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22773         unlinkmany $dom 1000
22774         return 0
22775 }
22776 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22777
22778 cleanup_271def_tests() {
22779         trap 0
22780         rm -f $1
22781 }
22782
22783 test_271d() {
22784         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22785                 skip "Need MDS version at least 2.10.57"
22786
22787         local dom=$DIR/$tdir/dom
22788         local tmp=$TMP/$tfile
22789         trap "cleanup_271def_tests $tmp" EXIT
22790
22791         mkdir -p $DIR/$tdir
22792
22793         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22794
22795         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22796
22797         cancel_lru_locks mdc
22798         dd if=/dev/urandom of=$tmp bs=1000 count=1
22799         dd if=$tmp of=$dom bs=1000 count=1
22800         cancel_lru_locks mdc
22801
22802         cat /etc/hosts >> $tmp
22803         lctl set_param -n mdc.*.stats=clear
22804
22805         # append data to the same file it should update local page
22806         echo "Append to the same page"
22807         cat /etc/hosts >> $dom
22808         local num=$(get_mdc_stats $mdtidx ost_read)
22809         local ra=$(get_mdc_stats $mdtidx req_active)
22810         local rw=$(get_mdc_stats $mdtidx req_waittime)
22811
22812         [ -z $num ] || error "$num READ RPC occured"
22813         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22814         echo "... DONE"
22815
22816         # compare content
22817         cmp $tmp $dom || error "file miscompare"
22818
22819         cancel_lru_locks mdc
22820         lctl set_param -n mdc.*.stats=clear
22821
22822         echo "Open and read file"
22823         cat $dom > /dev/null
22824         local num=$(get_mdc_stats $mdtidx ost_read)
22825         local ra=$(get_mdc_stats $mdtidx req_active)
22826         local rw=$(get_mdc_stats $mdtidx req_waittime)
22827
22828         [ -z $num ] || error "$num READ RPC occured"
22829         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22830         echo "... DONE"
22831
22832         # compare content
22833         cmp $tmp $dom || error "file miscompare"
22834
22835         return 0
22836 }
22837 run_test 271d "DoM: read on open (1K file in reply buffer)"
22838
22839 test_271f() {
22840         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22841                 skip "Need MDS version at least 2.10.57"
22842
22843         local dom=$DIR/$tdir/dom
22844         local tmp=$TMP/$tfile
22845         trap "cleanup_271def_tests $tmp" EXIT
22846
22847         mkdir -p $DIR/$tdir
22848
22849         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22850
22851         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22852
22853         cancel_lru_locks mdc
22854         dd if=/dev/urandom of=$tmp bs=265000 count=1
22855         dd if=$tmp of=$dom bs=265000 count=1
22856         cancel_lru_locks mdc
22857         cat /etc/hosts >> $tmp
22858         lctl set_param -n mdc.*.stats=clear
22859
22860         echo "Append to the same page"
22861         cat /etc/hosts >> $dom
22862         local num=$(get_mdc_stats $mdtidx ost_read)
22863         local ra=$(get_mdc_stats $mdtidx req_active)
22864         local rw=$(get_mdc_stats $mdtidx req_waittime)
22865
22866         [ -z $num ] || error "$num READ RPC occured"
22867         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22868         echo "... DONE"
22869
22870         # compare content
22871         cmp $tmp $dom || error "file miscompare"
22872
22873         cancel_lru_locks mdc
22874         lctl set_param -n mdc.*.stats=clear
22875
22876         echo "Open and read file"
22877         cat $dom > /dev/null
22878         local num=$(get_mdc_stats $mdtidx ost_read)
22879         local ra=$(get_mdc_stats $mdtidx req_active)
22880         local rw=$(get_mdc_stats $mdtidx req_waittime)
22881
22882         [ -z $num ] && num=0
22883         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22884         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22885         echo "... DONE"
22886
22887         # compare content
22888         cmp $tmp $dom || error "file miscompare"
22889
22890         return 0
22891 }
22892 run_test 271f "DoM: read on open (200K file and read tail)"
22893
22894 test_271g() {
22895         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22896                 skip "Skipping due to old client or server version"
22897
22898         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22899         # to get layout
22900         $CHECKSTAT -t file $DIR1/$tfile
22901
22902         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22903         MULTIOP_PID=$!
22904         sleep 1
22905         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22906         $LCTL set_param fail_loc=0x80000314
22907         rm $DIR1/$tfile || error "Unlink fails"
22908         RC=$?
22909         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22910         [ $RC -eq 0 ] || error "Failed write to stale object"
22911 }
22912 run_test 271g "Discard DoM data vs client flush race"
22913
22914 test_272a() {
22915         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22916                 skip "Need MDS version at least 2.11.50"
22917
22918         local dom=$DIR/$tdir/dom
22919         mkdir -p $DIR/$tdir
22920
22921         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22922         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22923                 error "failed to write data into $dom"
22924         local old_md5=$(md5sum $dom)
22925
22926         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22927                 error "failed to migrate to the same DoM component"
22928
22929         local new_md5=$(md5sum $dom)
22930
22931         [ "$old_md5" == "$new_md5" ] ||
22932                 error "md5sum differ: $old_md5, $new_md5"
22933
22934         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22935                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22936 }
22937 run_test 272a "DoM migration: new layout with the same DOM component"
22938
22939 test_272b() {
22940         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22941                 skip "Need MDS version at least 2.11.50"
22942
22943         local dom=$DIR/$tdir/dom
22944         mkdir -p $DIR/$tdir
22945         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22946
22947         local mdtidx=$($LFS getstripe -m $dom)
22948         local mdtname=MDT$(printf %04x $mdtidx)
22949         local facet=mds$((mdtidx + 1))
22950
22951         local mdtfree1=$(do_facet $facet \
22952                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22953         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22954                 error "failed to write data into $dom"
22955         local old_md5=$(md5sum $dom)
22956         cancel_lru_locks mdc
22957         local mdtfree1=$(do_facet $facet \
22958                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22959
22960         $LFS migrate -c2 $dom ||
22961                 error "failed to migrate to the new composite layout"
22962         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22963                 error "MDT stripe was not removed"
22964
22965         cancel_lru_locks mdc
22966         local new_md5=$(md5sum $dom)
22967         [ "$old_md5" == "$new_md5" ] ||
22968                 error "$old_md5 != $new_md5"
22969
22970         # Skip free space checks with ZFS
22971         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22972                 local mdtfree2=$(do_facet $facet \
22973                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22974                 [ $mdtfree2 -gt $mdtfree1 ] ||
22975                         error "MDT space is not freed after migration"
22976         fi
22977         return 0
22978 }
22979 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22980
22981 test_272c() {
22982         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22983                 skip "Need MDS version at least 2.11.50"
22984
22985         local dom=$DIR/$tdir/$tfile
22986         mkdir -p $DIR/$tdir
22987         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22988
22989         local mdtidx=$($LFS getstripe -m $dom)
22990         local mdtname=MDT$(printf %04x $mdtidx)
22991         local facet=mds$((mdtidx + 1))
22992
22993         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22994                 error "failed to write data into $dom"
22995         local old_md5=$(md5sum $dom)
22996         cancel_lru_locks mdc
22997         local mdtfree1=$(do_facet $facet \
22998                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22999
23000         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23001                 error "failed to migrate to the new composite layout"
23002         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23003                 error "MDT stripe was not removed"
23004
23005         cancel_lru_locks mdc
23006         local new_md5=$(md5sum $dom)
23007         [ "$old_md5" == "$new_md5" ] ||
23008                 error "$old_md5 != $new_md5"
23009
23010         # Skip free space checks with ZFS
23011         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23012                 local mdtfree2=$(do_facet $facet \
23013                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23014                 [ $mdtfree2 -gt $mdtfree1 ] ||
23015                         error "MDS space is not freed after migration"
23016         fi
23017         return 0
23018 }
23019 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23020
23021 test_272d() {
23022         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23023                 skip "Need MDS version at least 2.12.55"
23024
23025         local dom=$DIR/$tdir/$tfile
23026         mkdir -p $DIR/$tdir
23027         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23028
23029         local mdtidx=$($LFS getstripe -m $dom)
23030         local mdtname=MDT$(printf %04x $mdtidx)
23031         local facet=mds$((mdtidx + 1))
23032
23033         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23034                 error "failed to write data into $dom"
23035         local old_md5=$(md5sum $dom)
23036         cancel_lru_locks mdc
23037         local mdtfree1=$(do_facet $facet \
23038                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23039
23040         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23041                 error "failed mirroring to the new composite layout"
23042         $LFS mirror resync $dom ||
23043                 error "failed mirror resync"
23044         $LFS mirror split --mirror-id 1 -d $dom ||
23045                 error "failed mirror split"
23046
23047         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23048                 error "MDT stripe was not removed"
23049
23050         cancel_lru_locks mdc
23051         local new_md5=$(md5sum $dom)
23052         [ "$old_md5" == "$new_md5" ] ||
23053                 error "$old_md5 != $new_md5"
23054
23055         # Skip free space checks with ZFS
23056         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23057                 local mdtfree2=$(do_facet $facet \
23058                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23059                 [ $mdtfree2 -gt $mdtfree1 ] ||
23060                         error "MDS space is not freed after DOM mirror deletion"
23061         fi
23062         return 0
23063 }
23064 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23065
23066 test_272e() {
23067         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23068                 skip "Need MDS version at least 2.12.55"
23069
23070         local dom=$DIR/$tdir/$tfile
23071         mkdir -p $DIR/$tdir
23072         $LFS setstripe -c 2 $dom
23073
23074         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23075                 error "failed to write data into $dom"
23076         local old_md5=$(md5sum $dom)
23077         cancel_lru_locks
23078
23079         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23080                 error "failed mirroring to the DOM layout"
23081         $LFS mirror resync $dom ||
23082                 error "failed mirror resync"
23083         $LFS mirror split --mirror-id 1 -d $dom ||
23084                 error "failed mirror split"
23085
23086         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23087                 error "MDT stripe wasn't set"
23088
23089         cancel_lru_locks
23090         local new_md5=$(md5sum $dom)
23091         [ "$old_md5" == "$new_md5" ] ||
23092                 error "$old_md5 != $new_md5"
23093
23094         return 0
23095 }
23096 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23097
23098 test_272f() {
23099         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23100                 skip "Need MDS version at least 2.12.55"
23101
23102         local dom=$DIR/$tdir/$tfile
23103         mkdir -p $DIR/$tdir
23104         $LFS setstripe -c 2 $dom
23105
23106         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23107                 error "failed to write data into $dom"
23108         local old_md5=$(md5sum $dom)
23109         cancel_lru_locks
23110
23111         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23112                 error "failed migrating to the DOM file"
23113
23114         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23115                 error "MDT stripe wasn't set"
23116
23117         cancel_lru_locks
23118         local new_md5=$(md5sum $dom)
23119         [ "$old_md5" != "$new_md5" ] &&
23120                 error "$old_md5 != $new_md5"
23121
23122         return 0
23123 }
23124 run_test 272f "DoM migration: OST-striped file to DOM file"
23125
23126 test_273a() {
23127         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23128                 skip "Need MDS version at least 2.11.50"
23129
23130         # Layout swap cannot be done if either file has DOM component,
23131         # this will never be supported, migration should be used instead
23132
23133         local dom=$DIR/$tdir/$tfile
23134         mkdir -p $DIR/$tdir
23135
23136         $LFS setstripe -c2 ${dom}_plain
23137         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23138         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23139                 error "can swap layout with DoM component"
23140         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23141                 error "can swap layout with DoM component"
23142
23143         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23144         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23145                 error "can swap layout with DoM component"
23146         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23147                 error "can swap layout with DoM component"
23148         return 0
23149 }
23150 run_test 273a "DoM: layout swapping should fail with DOM"
23151
23152 test_273b() {
23153         mkdir -p $DIR/$tdir
23154         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23155
23156 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23157         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23158
23159         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23160 }
23161 run_test 273b "DoM: race writeback and object destroy"
23162
23163 test_275() {
23164         remote_ost_nodsh && skip "remote OST with nodsh"
23165         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23166                 skip "Need OST version >= 2.10.57"
23167
23168         local file=$DIR/$tfile
23169         local oss
23170
23171         oss=$(comma_list $(osts_nodes))
23172
23173         dd if=/dev/urandom of=$file bs=1M count=2 ||
23174                 error "failed to create a file"
23175         cancel_lru_locks osc
23176
23177         #lock 1
23178         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23179                 error "failed to read a file"
23180
23181 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23182         $LCTL set_param fail_loc=0x8000031f
23183
23184         cancel_lru_locks osc &
23185         sleep 1
23186
23187 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23188         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23189         #IO takes another lock, but matches the PENDING one
23190         #and places it to the IO RPC
23191         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23192                 error "failed to read a file with PENDING lock"
23193 }
23194 run_test 275 "Read on a canceled duplicate lock"
23195
23196 test_276() {
23197         remote_ost_nodsh && skip "remote OST with nodsh"
23198         local pid
23199
23200         do_facet ost1 "(while true; do \
23201                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23202                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23203         pid=$!
23204
23205         for LOOP in $(seq 20); do
23206                 stop ost1
23207                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23208         done
23209         kill -9 $pid
23210         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23211                 rm $TMP/sanity_276_pid"
23212 }
23213 run_test 276 "Race between mount and obd_statfs"
23214
23215 test_277() {
23216         $LCTL set_param ldlm.namespaces.*.lru_size=0
23217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23218         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23219                         grep ^used_mb | awk '{print $2}')
23220         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23221         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23222                 oflag=direct conv=notrunc
23223         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23224                         grep ^used_mb | awk '{print $2}')
23225         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23226 }
23227 run_test 277 "Direct IO shall drop page cache"
23228
23229 test_278() {
23230         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23231         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23232         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23233                 skip "needs the same host for mdt1 mdt2" && return
23234
23235         local pid1
23236         local pid2
23237
23238 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23239         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23240         stop mds2 &
23241         pid2=$!
23242
23243         stop mds1
23244
23245         echo "Starting MDTs"
23246         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23247         wait $pid2
23248 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23249 #will return NULL
23250         do_facet mds2 $LCTL set_param fail_loc=0
23251
23252         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23253         wait_recovery_complete mds2
23254 }
23255 run_test 278 "Race starting MDS between MDTs stop/start"
23256
23257 test_280() {
23258         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23259                 skip "Need MGS version at least 2.13.52"
23260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23261         combined_mgs_mds || skip "needs combined MGS/MDT"
23262
23263         umount_client $MOUNT
23264 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23265         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23266
23267         mount_client $MOUNT &
23268         sleep 1
23269         stop mgs || error "stop mgs failed"
23270         #for a race mgs would crash
23271         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23272         # make sure we unmount client before remounting
23273         wait
23274         umount_client $MOUNT
23275         mount_client $MOUNT || error "mount client failed"
23276 }
23277 run_test 280 "Race between MGS umount and client llog processing"
23278
23279 cleanup_test_300() {
23280         trap 0
23281         umask $SAVE_UMASK
23282 }
23283 test_striped_dir() {
23284         local mdt_index=$1
23285         local stripe_count
23286         local stripe_index
23287
23288         mkdir -p $DIR/$tdir
23289
23290         SAVE_UMASK=$(umask)
23291         trap cleanup_test_300 RETURN EXIT
23292
23293         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23294                                                 $DIR/$tdir/striped_dir ||
23295                 error "set striped dir error"
23296
23297         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23298         [ "$mode" = "755" ] || error "expect 755 got $mode"
23299
23300         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23301                 error "getdirstripe failed"
23302         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23303         if [ "$stripe_count" != "2" ]; then
23304                 error "1:stripe_count is $stripe_count, expect 2"
23305         fi
23306         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23307         if [ "$stripe_count" != "2" ]; then
23308                 error "2:stripe_count is $stripe_count, expect 2"
23309         fi
23310
23311         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23312         if [ "$stripe_index" != "$mdt_index" ]; then
23313                 error "stripe_index is $stripe_index, expect $mdt_index"
23314         fi
23315
23316         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23317                 error "nlink error after create striped dir"
23318
23319         mkdir $DIR/$tdir/striped_dir/a
23320         mkdir $DIR/$tdir/striped_dir/b
23321
23322         stat $DIR/$tdir/striped_dir/a ||
23323                 error "create dir under striped dir failed"
23324         stat $DIR/$tdir/striped_dir/b ||
23325                 error "create dir under striped dir failed"
23326
23327         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23328                 error "nlink error after mkdir"
23329
23330         rmdir $DIR/$tdir/striped_dir/a
23331         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23332                 error "nlink error after rmdir"
23333
23334         rmdir $DIR/$tdir/striped_dir/b
23335         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23336                 error "nlink error after rmdir"
23337
23338         chattr +i $DIR/$tdir/striped_dir
23339         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23340                 error "immutable flags not working under striped dir!"
23341         chattr -i $DIR/$tdir/striped_dir
23342
23343         rmdir $DIR/$tdir/striped_dir ||
23344                 error "rmdir striped dir error"
23345
23346         cleanup_test_300
23347
23348         true
23349 }
23350
23351 test_300a() {
23352         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23353                 skip "skipped for lustre < 2.7.0"
23354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23356
23357         test_striped_dir 0 || error "failed on striped dir on MDT0"
23358         test_striped_dir 1 || error "failed on striped dir on MDT0"
23359 }
23360 run_test 300a "basic striped dir sanity test"
23361
23362 test_300b() {
23363         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23364                 skip "skipped for lustre < 2.7.0"
23365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23367
23368         local i
23369         local mtime1
23370         local mtime2
23371         local mtime3
23372
23373         test_mkdir $DIR/$tdir || error "mkdir fail"
23374         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23375                 error "set striped dir error"
23376         for i in {0..9}; do
23377                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23378                 sleep 1
23379                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23380                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23381                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23382                 sleep 1
23383                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23384                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23385                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23386         done
23387         true
23388 }
23389 run_test 300b "check ctime/mtime for striped dir"
23390
23391 test_300c() {
23392         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23393                 skip "skipped for lustre < 2.7.0"
23394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23395         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23396
23397         local file_count
23398
23399         mkdir_on_mdt0 $DIR/$tdir
23400         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23401                 error "set striped dir error"
23402
23403         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23404                 error "chown striped dir failed"
23405
23406         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23407                 error "create 5k files failed"
23408
23409         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23410
23411         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23412
23413         rm -rf $DIR/$tdir
23414 }
23415 run_test 300c "chown && check ls under striped directory"
23416
23417 test_300d() {
23418         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23419                 skip "skipped for lustre < 2.7.0"
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         $LFS setstripe -c 2 $DIR/$tdir
23428
23429         #local striped directory
23430         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23431                 error "set striped dir error"
23432         #look at the directories for debug purposes
23433         ls -l $DIR/$tdir
23434         $LFS getdirstripe $DIR/$tdir
23435         ls -l $DIR/$tdir/striped_dir
23436         $LFS getdirstripe $DIR/$tdir/striped_dir
23437         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23438                 error "create 10 files failed"
23439
23440         #remote striped directory
23441         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23442                 error "set striped dir error"
23443         #look at the directories for debug purposes
23444         ls -l $DIR/$tdir
23445         $LFS getdirstripe $DIR/$tdir
23446         ls -l $DIR/$tdir/remote_striped_dir
23447         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23448         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23449                 error "create 10 files failed"
23450
23451         for file in $(find $DIR/$tdir); do
23452                 stripe_count=$($LFS getstripe -c $file)
23453                 [ $stripe_count -eq 2 ] ||
23454                         error "wrong stripe $stripe_count for $file"
23455         done
23456
23457         rm -rf $DIR/$tdir
23458 }
23459 run_test 300d "check default stripe under striped directory"
23460
23461 test_300e() {
23462         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23463                 skip "Need MDS version at least 2.7.55"
23464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23465         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23466
23467         local stripe_count
23468         local file
23469
23470         mkdir -p $DIR/$tdir
23471
23472         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23473                 error "set striped dir error"
23474
23475         touch $DIR/$tdir/striped_dir/a
23476         touch $DIR/$tdir/striped_dir/b
23477         touch $DIR/$tdir/striped_dir/c
23478
23479         mkdir $DIR/$tdir/striped_dir/dir_a
23480         mkdir $DIR/$tdir/striped_dir/dir_b
23481         mkdir $DIR/$tdir/striped_dir/dir_c
23482
23483         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23484                 error "set striped adir under striped dir error"
23485
23486         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23487                 error "set striped bdir under striped dir error"
23488
23489         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23490                 error "set striped cdir under striped dir error"
23491
23492         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23493                 error "rename dir under striped dir fails"
23494
23495         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23496                 error "rename dir under different stripes fails"
23497
23498         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23499                 error "rename file under striped dir should succeed"
23500
23501         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23502                 error "rename dir under striped dir should succeed"
23503
23504         rm -rf $DIR/$tdir
23505 }
23506 run_test 300e "check rename under striped directory"
23507
23508 test_300f() {
23509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23510         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23511         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23512                 skip "Need MDS version at least 2.7.55"
23513
23514         local stripe_count
23515         local file
23516
23517         rm -rf $DIR/$tdir
23518         mkdir -p $DIR/$tdir
23519
23520         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23521                 error "set striped dir error"
23522
23523         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23524                 error "set striped dir error"
23525
23526         touch $DIR/$tdir/striped_dir/a
23527         mkdir $DIR/$tdir/striped_dir/dir_a
23528         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23529                 error "create striped dir under striped dir fails"
23530
23531         touch $DIR/$tdir/striped_dir1/b
23532         mkdir $DIR/$tdir/striped_dir1/dir_b
23533         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23534                 error "create striped dir under striped dir fails"
23535
23536         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23537                 error "rename dir under different striped dir should fail"
23538
23539         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23540                 error "rename striped dir under diff striped dir should fail"
23541
23542         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23543                 error "rename file under diff striped dirs fails"
23544
23545         rm -rf $DIR/$tdir
23546 }
23547 run_test 300f "check rename cross striped directory"
23548
23549 test_300_check_default_striped_dir()
23550 {
23551         local dirname=$1
23552         local default_count=$2
23553         local default_index=$3
23554         local stripe_count
23555         local stripe_index
23556         local dir_stripe_index
23557         local dir
23558
23559         echo "checking $dirname $default_count $default_index"
23560         $LFS setdirstripe -D -c $default_count -i $default_index \
23561                                 -H all_char $DIR/$tdir/$dirname ||
23562                 error "set default stripe on striped dir error"
23563         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23564         [ $stripe_count -eq $default_count ] ||
23565                 error "expect $default_count get $stripe_count for $dirname"
23566
23567         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23568         [ $stripe_index -eq $default_index ] ||
23569                 error "expect $default_index get $stripe_index for $dirname"
23570
23571         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23572                                                 error "create dirs failed"
23573
23574         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23575         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23576         for dir in $(find $DIR/$tdir/$dirname/*); do
23577                 stripe_count=$($LFS getdirstripe -c $dir)
23578                 (( $stripe_count == $default_count )) ||
23579                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23580                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23581                 error "stripe count $default_count != $stripe_count for $dir"
23582
23583                 stripe_index=$($LFS getdirstripe -i $dir)
23584                 [ $default_index -eq -1 ] ||
23585                         [ $stripe_index -eq $default_index ] ||
23586                         error "$stripe_index != $default_index for $dir"
23587
23588                 #check default stripe
23589                 stripe_count=$($LFS getdirstripe -D -c $dir)
23590                 [ $stripe_count -eq $default_count ] ||
23591                 error "default count $default_count != $stripe_count for $dir"
23592
23593                 stripe_index=$($LFS getdirstripe -D -i $dir)
23594                 [ $stripe_index -eq $default_index ] ||
23595                 error "default index $default_index != $stripe_index for $dir"
23596         done
23597         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23598 }
23599
23600 test_300g() {
23601         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23602         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23603                 skip "Need MDS version at least 2.7.55"
23604
23605         local dir
23606         local stripe_count
23607         local stripe_index
23608
23609         mkdir_on_mdt0 $DIR/$tdir
23610         mkdir $DIR/$tdir/normal_dir
23611
23612         #Checking when client cache stripe index
23613         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23614         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23615                 error "create striped_dir failed"
23616
23617         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23618                 error "create dir0 fails"
23619         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23620         [ $stripe_index -eq 0 ] ||
23621                 error "dir0 expect index 0 got $stripe_index"
23622
23623         mkdir $DIR/$tdir/striped_dir/dir1 ||
23624                 error "create dir1 fails"
23625         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23626         [ $stripe_index -eq 1 ] ||
23627                 error "dir1 expect index 1 got $stripe_index"
23628
23629         #check default stripe count/stripe index
23630         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23631         test_300_check_default_striped_dir normal_dir 1 0
23632         test_300_check_default_striped_dir normal_dir -1 1
23633         test_300_check_default_striped_dir normal_dir 2 -1
23634
23635         #delete default stripe information
23636         echo "delete default stripeEA"
23637         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23638                 error "set default stripe on striped dir error"
23639
23640         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23641         for dir in $(find $DIR/$tdir/normal_dir/*); do
23642                 stripe_count=$($LFS getdirstripe -c $dir)
23643                 [ $stripe_count -eq 0 ] ||
23644                         error "expect 1 get $stripe_count for $dir"
23645         done
23646 }
23647 run_test 300g "check default striped directory for normal directory"
23648
23649 test_300h() {
23650         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23651         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23652                 skip "Need MDS version at least 2.7.55"
23653
23654         local dir
23655         local stripe_count
23656
23657         mkdir $DIR/$tdir
23658         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23659                 error "set striped dir error"
23660
23661         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23662         test_300_check_default_striped_dir striped_dir 1 0
23663         test_300_check_default_striped_dir striped_dir -1 1
23664         test_300_check_default_striped_dir striped_dir 2 -1
23665
23666         #delete default stripe information
23667         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23668                 error "set default stripe on striped dir error"
23669
23670         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23671         for dir in $(find $DIR/$tdir/striped_dir/*); do
23672                 stripe_count=$($LFS getdirstripe -c $dir)
23673                 [ $stripe_count -eq 0 ] ||
23674                         error "expect 1 get $stripe_count for $dir"
23675         done
23676 }
23677 run_test 300h "check default striped directory for striped directory"
23678
23679 test_300i() {
23680         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23681         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23682         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23683                 skip "Need MDS version at least 2.7.55"
23684
23685         local stripe_count
23686         local file
23687
23688         mkdir $DIR/$tdir
23689
23690         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23691                 error "set striped dir error"
23692
23693         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23694                 error "create files under striped dir failed"
23695
23696         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23697                 error "set striped hashdir error"
23698
23699         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23700                 error "create dir0 under hash dir failed"
23701         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23702                 error "create dir1 under hash dir failed"
23703         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23704                 error "create dir2 under hash dir failed"
23705
23706         # unfortunately, we need to umount to clear dir layout cache for now
23707         # once we fully implement dir layout, we can drop this
23708         umount_client $MOUNT || error "umount failed"
23709         mount_client $MOUNT || error "mount failed"
23710
23711         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23712         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23713         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23714
23715         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23716                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23717                         error "create crush2 dir $tdir/hashdir/d3 failed"
23718                 $LFS find -H crush2 $DIR/$tdir/hashdir
23719                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23720                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23721
23722                 # mkdir with an invalid hash type (hash=fail_val) from client
23723                 # should be replaced on MDS with a valid (default) hash type
23724                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23725                 $LCTL set_param fail_loc=0x1901 fail_val=99
23726                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23727
23728                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23729                 local expect=$(do_facet mds1 \
23730                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23731                 [[ $hash == $expect ]] ||
23732                         error "d99 hash '$hash' != expected hash '$expect'"
23733         fi
23734
23735         #set the stripe to be unknown hash type on read
23736         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23737         $LCTL set_param fail_loc=0x1901 fail_val=99
23738         for ((i = 0; i < 10; i++)); do
23739                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23740                         error "stat f-$i failed"
23741                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23742         done
23743
23744         touch $DIR/$tdir/striped_dir/f0 &&
23745                 error "create under striped dir with unknown hash should fail"
23746
23747         $LCTL set_param fail_loc=0
23748
23749         umount_client $MOUNT || error "umount failed"
23750         mount_client $MOUNT || error "mount failed"
23751
23752         return 0
23753 }
23754 run_test 300i "client handle unknown hash type striped directory"
23755
23756 test_300j() {
23757         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23759         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23760                 skip "Need MDS version at least 2.7.55"
23761
23762         local stripe_count
23763         local file
23764
23765         mkdir $DIR/$tdir
23766
23767         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23768         $LCTL set_param fail_loc=0x1702
23769         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23770                 error "set striped dir error"
23771
23772         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23773                 error "create files under striped dir failed"
23774
23775         $LCTL set_param fail_loc=0
23776
23777         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23778
23779         return 0
23780 }
23781 run_test 300j "test large update record"
23782
23783 test_300k() {
23784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23785         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23786         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23787                 skip "Need MDS version at least 2.7.55"
23788
23789         # this test needs a huge transaction
23790         local kb
23791         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23792              osd*.$FSNAME-MDT0000.kbytestotal")
23793         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23794
23795         local stripe_count
23796         local file
23797
23798         mkdir $DIR/$tdir
23799
23800         #define OBD_FAIL_LARGE_STRIPE   0x1703
23801         $LCTL set_param fail_loc=0x1703
23802         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23803                 error "set striped dir error"
23804         $LCTL set_param fail_loc=0
23805
23806         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23807                 error "getstripeddir fails"
23808         rm -rf $DIR/$tdir/striped_dir ||
23809                 error "unlink striped dir fails"
23810
23811         return 0
23812 }
23813 run_test 300k "test large striped directory"
23814
23815 test_300l() {
23816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23818         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23819                 skip "Need MDS version at least 2.7.55"
23820
23821         local stripe_index
23822
23823         test_mkdir -p $DIR/$tdir/striped_dir
23824         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23825                         error "chown $RUNAS_ID failed"
23826         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23827                 error "set default striped dir failed"
23828
23829         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23830         $LCTL set_param fail_loc=0x80000158
23831         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23832
23833         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23834         [ $stripe_index -eq 1 ] ||
23835                 error "expect 1 get $stripe_index for $dir"
23836 }
23837 run_test 300l "non-root user to create dir under striped dir with stale layout"
23838
23839 test_300m() {
23840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23841         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23842         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23843                 skip "Need MDS version at least 2.7.55"
23844
23845         mkdir -p $DIR/$tdir/striped_dir
23846         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23847                 error "set default stripes dir error"
23848
23849         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23850
23851         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23852         [ $stripe_count -eq 0 ] ||
23853                         error "expect 0 get $stripe_count for a"
23854
23855         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23856                 error "set default stripes dir error"
23857
23858         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23859
23860         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23861         [ $stripe_count -eq 0 ] ||
23862                         error "expect 0 get $stripe_count for b"
23863
23864         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23865                 error "set default stripes dir error"
23866
23867         mkdir $DIR/$tdir/striped_dir/c &&
23868                 error "default stripe_index is invalid, mkdir c should fails"
23869
23870         rm -rf $DIR/$tdir || error "rmdir fails"
23871 }
23872 run_test 300m "setstriped directory on single MDT FS"
23873
23874 cleanup_300n() {
23875         local list=$(comma_list $(mdts_nodes))
23876
23877         trap 0
23878         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23879 }
23880
23881 test_300n() {
23882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23883         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23884         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23885                 skip "Need MDS version at least 2.7.55"
23886         remote_mds_nodsh && skip "remote MDS with nodsh"
23887
23888         local stripe_index
23889         local list=$(comma_list $(mdts_nodes))
23890
23891         trap cleanup_300n RETURN EXIT
23892         mkdir -p $DIR/$tdir
23893         chmod 777 $DIR/$tdir
23894         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23895                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23896                 error "create striped dir succeeds with gid=0"
23897
23898         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23899         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23900                 error "create striped dir fails with gid=-1"
23901
23902         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23903         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23904                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23905                 error "set default striped dir succeeds with gid=0"
23906
23907
23908         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23909         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23910                 error "set default striped dir fails with gid=-1"
23911
23912
23913         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23914         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23915                                         error "create test_dir fails"
23916         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23917                                         error "create test_dir1 fails"
23918         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23919                                         error "create test_dir2 fails"
23920         cleanup_300n
23921 }
23922 run_test 300n "non-root user to create dir under striped dir with default EA"
23923
23924 test_300o() {
23925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23926         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23927         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23928                 skip "Need MDS version at least 2.7.55"
23929
23930         local numfree1
23931         local numfree2
23932
23933         mkdir -p $DIR/$tdir
23934
23935         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23936         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23937         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23938                 skip "not enough free inodes $numfree1 $numfree2"
23939         fi
23940
23941         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23942         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23943         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23944                 skip "not enough free space $numfree1 $numfree2"
23945         fi
23946
23947         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23948                 error "setdirstripe fails"
23949
23950         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23951                 error "create dirs fails"
23952
23953         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23954         ls $DIR/$tdir/striped_dir > /dev/null ||
23955                 error "ls striped dir fails"
23956         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23957                 error "unlink big striped dir fails"
23958 }
23959 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23960
23961 test_300p() {
23962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23963         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23964         remote_mds_nodsh && skip "remote MDS with nodsh"
23965
23966         mkdir_on_mdt0 $DIR/$tdir
23967
23968         #define OBD_FAIL_OUT_ENOSPC     0x1704
23969         do_facet mds2 lctl set_param fail_loc=0x80001704
23970         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23971                  && error "create striped directory should fail"
23972
23973         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23974
23975         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23976         true
23977 }
23978 run_test 300p "create striped directory without space"
23979
23980 test_300q() {
23981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23982         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23983
23984         local fd=$(free_fd)
23985         local cmd="exec $fd<$tdir"
23986         cd $DIR
23987         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23988         eval $cmd
23989         cmd="exec $fd<&-"
23990         trap "eval $cmd" EXIT
23991         cd $tdir || error "cd $tdir fails"
23992         rmdir  ../$tdir || error "rmdir $tdir fails"
23993         mkdir local_dir && error "create dir succeeds"
23994         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23995         eval $cmd
23996         return 0
23997 }
23998 run_test 300q "create remote directory under orphan directory"
23999
24000 test_300r() {
24001         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24002                 skip "Need MDS version at least 2.7.55" && return
24003         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24004
24005         mkdir $DIR/$tdir
24006
24007         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24008                 error "set striped dir error"
24009
24010         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24011                 error "getstripeddir fails"
24012
24013         local stripe_count
24014         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24015                       awk '/lmv_stripe_count:/ { print $2 }')
24016
24017         [ $MDSCOUNT -ne $stripe_count ] &&
24018                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24019
24020         rm -rf $DIR/$tdir/striped_dir ||
24021                 error "unlink striped dir fails"
24022 }
24023 run_test 300r "test -1 striped directory"
24024
24025 test_300s_helper() {
24026         local count=$1
24027
24028         local stripe_dir=$DIR/$tdir/striped_dir.$count
24029
24030         $LFS mkdir -c $count $stripe_dir ||
24031                 error "lfs mkdir -c error"
24032
24033         $LFS getdirstripe $stripe_dir ||
24034                 error "lfs getdirstripe fails"
24035
24036         local stripe_count
24037         stripe_count=$($LFS getdirstripe $stripe_dir |
24038                       awk '/lmv_stripe_count:/ { print $2 }')
24039
24040         [ $count -ne $stripe_count ] &&
24041                 error_noexit "bad stripe count $stripe_count expected $count"
24042
24043         local dupe_stripes
24044         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24045                 awk '/0x/ {count[$1] += 1}; END {
24046                         for (idx in count) {
24047                                 if (count[idx]>1) {
24048                                         print "index " idx " count " count[idx]
24049                                 }
24050                         }
24051                 }')
24052
24053         if [[ -n "$dupe_stripes" ]] ; then
24054                 lfs getdirstripe $stripe_dir
24055                 error_noexit "Dupe MDT above: $dupe_stripes "
24056         fi
24057
24058         rm -rf $stripe_dir ||
24059                 error_noexit "unlink $stripe_dir fails"
24060 }
24061
24062 test_300s() {
24063         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24064                 skip "Need MDS version at least 2.7.55" && return
24065         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24066
24067         mkdir $DIR/$tdir
24068         for count in $(seq 2 $MDSCOUNT); do
24069                 test_300s_helper $count
24070         done
24071 }
24072 run_test 300s "test lfs mkdir -c without -i"
24073
24074 test_300t() {
24075         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24076                 skip "need MDS 2.14.55 or later"
24077         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24078
24079         local testdir="$DIR/$tdir/striped_dir"
24080         local dir1=$testdir/dir1
24081         local dir2=$testdir/dir2
24082
24083         mkdir -p $testdir
24084
24085         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24086                 error "failed to set default stripe count for $testdir"
24087
24088         mkdir $dir1
24089         local stripe_count=$($LFS getdirstripe -c $dir1)
24090
24091         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24092
24093         local max_count=$((MDSCOUNT - 1))
24094         local mdts=$(comma_list $(mdts_nodes))
24095
24096         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24097         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24098
24099         mkdir $dir2
24100         stripe_count=$($LFS getdirstripe -c $dir2)
24101
24102         (( $stripe_count == $max_count )) || error "wrong stripe count"
24103 }
24104 run_test 300t "test max_mdt_stripecount"
24105
24106 prepare_remote_file() {
24107         mkdir $DIR/$tdir/src_dir ||
24108                 error "create remote source failed"
24109
24110         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24111                  error "cp to remote source failed"
24112         touch $DIR/$tdir/src_dir/a
24113
24114         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24115                 error "create remote target dir failed"
24116
24117         touch $DIR/$tdir/tgt_dir/b
24118
24119         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24120                 error "rename dir cross MDT failed!"
24121
24122         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24123                 error "src_child still exists after rename"
24124
24125         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24126                 error "missing file(a) after rename"
24127
24128         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24129                 error "diff after rename"
24130 }
24131
24132 test_310a() {
24133         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24135
24136         local remote_file=$DIR/$tdir/tgt_dir/b
24137
24138         mkdir -p $DIR/$tdir
24139
24140         prepare_remote_file || error "prepare remote file failed"
24141
24142         #open-unlink file
24143         $OPENUNLINK $remote_file $remote_file ||
24144                 error "openunlink $remote_file failed"
24145         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24146 }
24147 run_test 310a "open unlink remote file"
24148
24149 test_310b() {
24150         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24152
24153         local remote_file=$DIR/$tdir/tgt_dir/b
24154
24155         mkdir -p $DIR/$tdir
24156
24157         prepare_remote_file || error "prepare remote file failed"
24158
24159         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24160         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24161         $CHECKSTAT -t file $remote_file || error "check file failed"
24162 }
24163 run_test 310b "unlink remote file with multiple links while open"
24164
24165 test_310c() {
24166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24167         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24168
24169         local remote_file=$DIR/$tdir/tgt_dir/b
24170
24171         mkdir -p $DIR/$tdir
24172
24173         prepare_remote_file || error "prepare remote file failed"
24174
24175         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24176         multiop_bg_pause $remote_file O_uc ||
24177                         error "mulitop failed for remote file"
24178         MULTIPID=$!
24179         $MULTIOP $DIR/$tfile Ouc
24180         kill -USR1 $MULTIPID
24181         wait $MULTIPID
24182 }
24183 run_test 310c "open-unlink remote file with multiple links"
24184
24185 #LU-4825
24186 test_311() {
24187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24188         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24189         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24190                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24191         remote_mds_nodsh && skip "remote MDS with nodsh"
24192
24193         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24194         local mdts=$(comma_list $(mdts_nodes))
24195
24196         mkdir -p $DIR/$tdir
24197         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24198         createmany -o $DIR/$tdir/$tfile. 1000
24199
24200         # statfs data is not real time, let's just calculate it
24201         old_iused=$((old_iused + 1000))
24202
24203         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24204                         osp.*OST0000*MDT0000.create_count")
24205         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24206                                 osp.*OST0000*MDT0000.max_create_count")
24207         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24208
24209         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24210         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24211         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24212
24213         unlinkmany $DIR/$tdir/$tfile. 1000
24214
24215         do_nodes $mdts "$LCTL set_param -n \
24216                         osp.*OST0000*.max_create_count=$max_count"
24217         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24218                 do_nodes $mdts "$LCTL set_param -n \
24219                                 osp.*OST0000*.create_count=$count"
24220         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24221                         grep "=0" && error "create_count is zero"
24222
24223         local new_iused
24224         for i in $(seq 120); do
24225                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24226                 # system may be too busy to destroy all objs in time, use
24227                 # a somewhat small value to not fail autotest
24228                 [ $((old_iused - new_iused)) -gt 400 ] && break
24229                 sleep 1
24230         done
24231
24232         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24233         [ $((old_iused - new_iused)) -gt 400 ] ||
24234                 error "objs not destroyed after unlink"
24235 }
24236 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24237
24238 zfs_oid_to_objid()
24239 {
24240         local ost=$1
24241         local objid=$2
24242
24243         local vdevdir=$(dirname $(facet_vdevice $ost))
24244         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24245         local zfs_zapid=$(do_facet $ost $cmd |
24246                           grep -w "/O/0/d$((objid%32))" -C 5 |
24247                           awk '/Object/{getline; print $1}')
24248         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24249                           awk "/$objid = /"'{printf $3}')
24250
24251         echo $zfs_objid
24252 }
24253
24254 zfs_object_blksz() {
24255         local ost=$1
24256         local objid=$2
24257
24258         local vdevdir=$(dirname $(facet_vdevice $ost))
24259         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24260         local blksz=$(do_facet $ost $cmd $objid |
24261                       awk '/dblk/{getline; printf $4}')
24262
24263         case "${blksz: -1}" in
24264                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24265                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24266                 *) ;;
24267         esac
24268
24269         echo $blksz
24270 }
24271
24272 test_312() { # LU-4856
24273         remote_ost_nodsh && skip "remote OST with nodsh"
24274         [ "$ost1_FSTYPE" = "zfs" ] ||
24275                 skip_env "the test only applies to zfs"
24276
24277         local max_blksz=$(do_facet ost1 \
24278                           $ZFS get -p recordsize $(facet_device ost1) |
24279                           awk '!/VALUE/{print $3}')
24280
24281         # to make life a little bit easier
24282         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24283         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24284
24285         local tf=$DIR/$tdir/$tfile
24286         touch $tf
24287         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24288
24289         # Get ZFS object id
24290         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24291         # block size change by sequential overwrite
24292         local bs
24293
24294         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24295                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24296
24297                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24298                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24299         done
24300         rm -f $tf
24301
24302         # block size change by sequential append write
24303         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24304         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24305         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24306         local count
24307
24308         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24309                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24310                         oflag=sync conv=notrunc
24311
24312                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24313                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24314                         error "blksz error, actual $blksz, " \
24315                                 "expected: 2 * $count * $PAGE_SIZE"
24316         done
24317         rm -f $tf
24318
24319         # random write
24320         touch $tf
24321         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24322         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24323
24324         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24325         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24326         [ $blksz -eq $PAGE_SIZE ] ||
24327                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24328
24329         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24330         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24331         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24332
24333         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24334         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24335         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24336 }
24337 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24338
24339 test_313() {
24340         remote_ost_nodsh && skip "remote OST with nodsh"
24341
24342         local file=$DIR/$tfile
24343
24344         rm -f $file
24345         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24346
24347         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24348         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24349         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24350                 error "write should failed"
24351         do_facet ost1 "$LCTL set_param fail_loc=0"
24352         rm -f $file
24353 }
24354 run_test 313 "io should fail after last_rcvd update fail"
24355
24356 test_314() {
24357         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24358
24359         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24360         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24361         rm -f $DIR/$tfile
24362         wait_delete_completed
24363         do_facet ost1 "$LCTL set_param fail_loc=0"
24364 }
24365 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24366
24367 test_315() { # LU-618
24368         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24369
24370         local file=$DIR/$tfile
24371         rm -f $file
24372
24373         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24374                 error "multiop file write failed"
24375         $MULTIOP $file oO_RDONLY:r4063232_c &
24376         PID=$!
24377
24378         sleep 2
24379
24380         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24381         kill -USR1 $PID
24382
24383         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24384         rm -f $file
24385 }
24386 run_test 315 "read should be accounted"
24387
24388 test_316() {
24389         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24390         large_xattr_enabled || skip "ea_inode feature disabled"
24391
24392         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24393         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24394         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24395         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24396
24397         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24398 }
24399 run_test 316 "lfs migrate of file with large_xattr enabled"
24400
24401 test_317() {
24402         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24403                 skip "Need MDS version at least 2.11.53"
24404         if [ "$ost1_FSTYPE" == "zfs" ]; then
24405                 skip "LU-10370: no implementation for ZFS"
24406         fi
24407
24408         local trunc_sz
24409         local grant_blk_size
24410
24411         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24412                         awk '/grant_block_size:/ { print $2; exit; }')
24413         #
24414         # Create File of size 5M. Truncate it to below size's and verify
24415         # blocks count.
24416         #
24417         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24418                 error "Create file $DIR/$tfile failed"
24419         stack_trap "rm -f $DIR/$tfile" EXIT
24420
24421         for trunc_sz in 2097152 4097 4000 509 0; do
24422                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24423                         error "truncate $tfile to $trunc_sz failed"
24424                 local sz=$(stat --format=%s $DIR/$tfile)
24425                 local blk=$(stat --format=%b $DIR/$tfile)
24426                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24427                                      grant_blk_size) * 8))
24428
24429                 if [[ $blk -ne $trunc_blk ]]; then
24430                         $(which stat) $DIR/$tfile
24431                         error "Expected Block $trunc_blk got $blk for $tfile"
24432                 fi
24433
24434                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24435                         error "Expected Size $trunc_sz got $sz for $tfile"
24436         done
24437
24438         #
24439         # sparse file test
24440         # Create file with a hole and write actual 65536 bytes which aligned
24441         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24442         #
24443         local bs=65536
24444         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24445                 error "Create file : $DIR/$tfile"
24446
24447         #
24448         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24449         # blocks. The block count must drop to 8.
24450         #
24451         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24452                 ((bs - grant_blk_size) + 1)))
24453         $TRUNCATE $DIR/$tfile $trunc_sz ||
24454                 error "truncate $tfile to $trunc_sz failed"
24455
24456         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24457         sz=$(stat --format=%s $DIR/$tfile)
24458         blk=$(stat --format=%b $DIR/$tfile)
24459
24460         if [[ $blk -ne $trunc_bsz ]]; then
24461                 $(which stat) $DIR/$tfile
24462                 error "Expected Block $trunc_bsz got $blk for $tfile"
24463         fi
24464
24465         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24466                 error "Expected Size $trunc_sz got $sz for $tfile"
24467 }
24468 run_test 317 "Verify blocks get correctly update after truncate"
24469
24470 test_318() {
24471         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24472         local old_max_active=$($LCTL get_param -n \
24473                             ${llite_name}.max_read_ahead_async_active \
24474                             2>/dev/null)
24475
24476         $LCTL set_param llite.*.max_read_ahead_async_active=256
24477         local max_active=$($LCTL get_param -n \
24478                            ${llite_name}.max_read_ahead_async_active \
24479                            2>/dev/null)
24480         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24481
24482         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24483                 error "set max_read_ahead_async_active should succeed"
24484
24485         $LCTL set_param llite.*.max_read_ahead_async_active=512
24486         max_active=$($LCTL get_param -n \
24487                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24488         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24489
24490         # restore @max_active
24491         [ $old_max_active -ne 0 ] && $LCTL set_param \
24492                 llite.*.max_read_ahead_async_active=$old_max_active
24493
24494         local old_threshold=$($LCTL get_param -n \
24495                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24496         local max_per_file_mb=$($LCTL get_param -n \
24497                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24498
24499         local invalid=$(($max_per_file_mb + 1))
24500         $LCTL set_param \
24501                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24502                         && error "set $invalid should fail"
24503
24504         local valid=$(($invalid - 1))
24505         $LCTL set_param \
24506                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24507                         error "set $valid should succeed"
24508         local threshold=$($LCTL get_param -n \
24509                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24510         [ $threshold -eq $valid ] || error \
24511                 "expect threshold $valid got $threshold"
24512         $LCTL set_param \
24513                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24514 }
24515 run_test 318 "Verify async readahead tunables"
24516
24517 test_319() {
24518         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24519
24520         local before=$(date +%s)
24521         local evict
24522         local mdir=$DIR/$tdir
24523         local file=$mdir/xxx
24524
24525         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24526         touch $file
24527
24528 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24529         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24530         $LFS migrate -m1 $mdir &
24531
24532         sleep 1
24533         dd if=$file of=/dev/null
24534         wait
24535         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24536           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24537
24538         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24539 }
24540 run_test 319 "lost lease lock on migrate error"
24541
24542 test_398a() { # LU-4198
24543         local ost1_imp=$(get_osc_import_name client ost1)
24544         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24545                          cut -d'.' -f2)
24546
24547         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24548         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24549
24550         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24551         # request a new lock on client
24552         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24553
24554         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24555         #local lock_count=$($LCTL get_param -n \
24556         #                  ldlm.namespaces.$imp_name.lru_size)
24557         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24558
24559         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24560
24561         # no lock cached, should use lockless DIO and not enqueue new lock
24562         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24563                 conv=notrunc ||
24564                 error "dio write failed"
24565         lock_count=$($LCTL get_param -n \
24566                      ldlm.namespaces.$imp_name.lru_size)
24567         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24568
24569         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24570
24571         # no lock cached, should use locked DIO append
24572         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24573                 conv=notrunc || error "DIO append failed"
24574         lock_count=$($LCTL get_param -n \
24575                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24576         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24577 }
24578 run_test 398a "direct IO should cancel lock otherwise lockless"
24579
24580 test_398b() { # LU-4198
24581         which fio || skip_env "no fio installed"
24582         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24583
24584         local size=48
24585         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24586
24587         local njobs=4
24588         # Single page, multiple pages, stripe size, 4*stripe size
24589         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24590                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24591                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24592                         --numjobs=$njobs --fallocate=none \
24593                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24594                         --filename=$DIR/$tfile &
24595                 bg_pid=$!
24596
24597                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24598                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24599                         --numjobs=$njobs --fallocate=none \
24600                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24601                         --filename=$DIR/$tfile || true
24602                 wait $bg_pid
24603         done
24604
24605         evict=$(do_facet client $LCTL get_param \
24606                 osc.$FSNAME-OST*-osc-*/state |
24607             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24608
24609         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24610                 (do_facet client $LCTL get_param \
24611                         osc.$FSNAME-OST*-osc-*/state;
24612                     error "eviction happened: $evict before:$before")
24613
24614         rm -f $DIR/$tfile
24615 }
24616 run_test 398b "DIO and buffer IO race"
24617
24618 test_398c() { # LU-4198
24619         local ost1_imp=$(get_osc_import_name client ost1)
24620         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24621                          cut -d'.' -f2)
24622
24623         which fio || skip_env "no fio installed"
24624
24625         saved_debug=$($LCTL get_param -n debug)
24626         $LCTL set_param debug=0
24627
24628         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24629         ((size /= 1024)) # by megabytes
24630         ((size /= 2)) # write half of the OST at most
24631         [ $size -gt 40 ] && size=40 #reduce test time anyway
24632
24633         $LFS setstripe -c 1 $DIR/$tfile
24634
24635         # it seems like ldiskfs reserves more space than necessary if the
24636         # writing blocks are not mapped, so it extends the file firstly
24637         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24638         cancel_lru_locks osc
24639
24640         # clear and verify rpc_stats later
24641         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24642
24643         local njobs=4
24644         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24645         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24646                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24647                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24648                 --filename=$DIR/$tfile
24649         [ $? -eq 0 ] || error "fio write error"
24650
24651         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24652                 error "Locks were requested while doing AIO"
24653
24654         # get the percentage of 1-page I/O
24655         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24656                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24657                 awk '{print $7}')
24658         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24659
24660         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24661         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24662                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24663                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24664                 --filename=$DIR/$tfile
24665         [ $? -eq 0 ] || error "fio mixed read write error"
24666
24667         echo "AIO with large block size ${size}M"
24668         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24669                 --numjobs=1 --fallocate=none --ioengine=libaio \
24670                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24671                 --filename=$DIR/$tfile
24672         [ $? -eq 0 ] || error "fio large block size failed"
24673
24674         rm -f $DIR/$tfile
24675         $LCTL set_param debug="$saved_debug"
24676 }
24677 run_test 398c "run fio to test AIO"
24678
24679 test_398d() { #  LU-13846
24680         which aiocp || skip_env "no aiocp installed"
24681         local aio_file=$DIR/$tfile.aio
24682
24683         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24684
24685         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24686         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24687         stack_trap "rm -f $DIR/$tfile $aio_file"
24688
24689         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24690
24691         # make sure we don't crash and fail properly
24692         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24693                 error "aio not aligned with PAGE SIZE should fail"
24694
24695         rm -f $DIR/$tfile $aio_file
24696 }
24697 run_test 398d "run aiocp to verify block size > stripe size"
24698
24699 test_398e() {
24700         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24701         touch $DIR/$tfile.new
24702         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24703 }
24704 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24705
24706 test_398f() { #  LU-14687
24707         which aiocp || skip_env "no aiocp installed"
24708         local aio_file=$DIR/$tfile.aio
24709
24710         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24711
24712         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24713         stack_trap "rm -f $DIR/$tfile $aio_file"
24714
24715         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24716         $LCTL set_param fail_loc=0x1418
24717         # make sure we don't crash and fail properly
24718         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24719                 error "aio with page allocation failure succeeded"
24720         $LCTL set_param fail_loc=0
24721         diff $DIR/$tfile $aio_file
24722         [[ $? != 0 ]] || error "no diff after failed aiocp"
24723 }
24724 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24725
24726 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24727 # stripe and i/o size must be > stripe size
24728 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24729 # single RPC in flight.  This test shows async DIO submission is working by
24730 # showing multiple RPCs in flight.
24731 test_398g() { #  LU-13798
24732         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24733
24734         # We need to do some i/o first to acquire enough grant to put our RPCs
24735         # in flight; otherwise a new connection may not have enough grant
24736         # available
24737         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24738                 error "parallel dio failed"
24739         stack_trap "rm -f $DIR/$tfile"
24740
24741         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24742         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24743         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24744         stack_trap "$LCTL set_param -n $pages_per_rpc"
24745
24746         # Recreate file so it's empty
24747         rm -f $DIR/$tfile
24748         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24749         #Pause rpc completion to guarantee we see multiple rpcs in flight
24750         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24751         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24752         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24753
24754         # Clear rpc stats
24755         $LCTL set_param osc.*.rpc_stats=c
24756
24757         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24758                 error "parallel dio failed"
24759         stack_trap "rm -f $DIR/$tfile"
24760
24761         $LCTL get_param osc.*-OST0000-*.rpc_stats
24762         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24763                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24764                 grep "8:" | awk '{print $8}')
24765         # We look at the "8 rpcs in flight" field, and verify A) it is present
24766         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24767         # as expected for an 8M DIO to a file with 1M stripes.
24768         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24769
24770         # Verify turning off parallel dio works as expected
24771         # Clear rpc stats
24772         $LCTL set_param osc.*.rpc_stats=c
24773         $LCTL set_param llite.*.parallel_dio=0
24774         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24775
24776         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24777                 error "dio with parallel dio disabled failed"
24778
24779         # Ideally, we would see only one RPC in flight here, but there is an
24780         # unavoidable race between i/o completion and RPC in flight counting,
24781         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24782         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24783         # So instead we just verify it's always < 8.
24784         $LCTL get_param osc.*-OST0000-*.rpc_stats
24785         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24786                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24787                 grep '^$' -B1 | grep . | awk '{print $1}')
24788         [ $ret != "8:" ] ||
24789                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24790 }
24791 run_test 398g "verify parallel dio async RPC submission"
24792
24793 test_398h() { #  LU-13798
24794         local dio_file=$DIR/$tfile.dio
24795
24796         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24797
24798         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24799         stack_trap "rm -f $DIR/$tfile $dio_file"
24800
24801         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24802                 error "parallel dio failed"
24803         diff $DIR/$tfile $dio_file
24804         [[ $? == 0 ]] || error "file diff after aiocp"
24805 }
24806 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24807
24808 test_398i() { #  LU-13798
24809         local dio_file=$DIR/$tfile.dio
24810
24811         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24812
24813         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24814         stack_trap "rm -f $DIR/$tfile $dio_file"
24815
24816         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24817         $LCTL set_param fail_loc=0x1418
24818         # make sure we don't crash and fail properly
24819         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24820                 error "parallel dio page allocation failure succeeded"
24821         diff $DIR/$tfile $dio_file
24822         [[ $? != 0 ]] || error "no diff after failed aiocp"
24823 }
24824 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24825
24826 test_398j() { #  LU-13798
24827         # Stripe size > RPC size but less than i/o size tests split across
24828         # stripes and RPCs for individual i/o op
24829         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24830
24831         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24832         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24833         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24834         stack_trap "$LCTL set_param -n $pages_per_rpc"
24835
24836         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24837                 error "parallel dio write failed"
24838         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24839
24840         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24841                 error "parallel dio read failed"
24842         diff $DIR/$tfile $DIR/$tfile.2
24843         [[ $? == 0 ]] || error "file diff after parallel dio read"
24844 }
24845 run_test 398j "test parallel dio where stripe size > rpc_size"
24846
24847 test_398k() { #  LU-13798
24848         wait_delete_completed
24849         wait_mds_ost_sync
24850
24851         # 4 stripe file; we will cause out of space on OST0
24852         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24853
24854         # Fill OST0 (if it's not too large)
24855         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24856                    head -n1)
24857         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24858                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24859         fi
24860         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24861         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24862                 error "dd should fill OST0"
24863         stack_trap "rm -f $DIR/$tfile.1"
24864
24865         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24866         err=$?
24867
24868         ls -la $DIR/$tfile
24869         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24870                 error "file is not 0 bytes in size"
24871
24872         # dd above should not succeed, but don't error until here so we can
24873         # get debug info above
24874         [[ $err != 0 ]] ||
24875                 error "parallel dio write with enospc succeeded"
24876         stack_trap "rm -f $DIR/$tfile"
24877 }
24878 run_test 398k "test enospc on first stripe"
24879
24880 test_398l() { #  LU-13798
24881         wait_delete_completed
24882         wait_mds_ost_sync
24883
24884         # 4 stripe file; we will cause out of space on OST0
24885         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24886         # happens on the second i/o chunk we issue
24887         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24888
24889         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24890         stack_trap "rm -f $DIR/$tfile"
24891
24892         # Fill OST0 (if it's not too large)
24893         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24894                    head -n1)
24895         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24896                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24897         fi
24898         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24899         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24900                 error "dd should fill OST0"
24901         stack_trap "rm -f $DIR/$tfile.1"
24902
24903         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24904         err=$?
24905         stack_trap "rm -f $DIR/$tfile.2"
24906
24907         # Check that short write completed as expected
24908         ls -la $DIR/$tfile.2
24909         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24910                 error "file is not 1M in size"
24911
24912         # dd above should not succeed, but don't error until here so we can
24913         # get debug info above
24914         [[ $err != 0 ]] ||
24915                 error "parallel dio write with enospc succeeded"
24916
24917         # Truncate source file to same length as output file and diff them
24918         $TRUNCATE $DIR/$tfile 1048576
24919         diff $DIR/$tfile $DIR/$tfile.2
24920         [[ $? == 0 ]] || error "data incorrect after short write"
24921 }
24922 run_test 398l "test enospc on intermediate stripe/RPC"
24923
24924 test_398m() { #  LU-13798
24925         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24926
24927         # Set up failure on OST0, the first stripe:
24928         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24929         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24930         # So this fail_val specifies OST0
24931         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24932         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24933
24934         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24935                 error "parallel dio write with failure on first stripe succeeded"
24936         stack_trap "rm -f $DIR/$tfile"
24937         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24938
24939         # Place data in file for read
24940         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24941                 error "parallel dio write failed"
24942
24943         # Fail read on OST0, first stripe
24944         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24945         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24946         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24947                 error "parallel dio read with error on first stripe succeeded"
24948         rm -f $DIR/$tfile.2
24949         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24950
24951         # Switch to testing on OST1, second stripe
24952         # Clear file contents, maintain striping
24953         echo > $DIR/$tfile
24954         # Set up failure on OST1, second stripe:
24955         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24956         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24957
24958         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24959                 error "parallel dio write with failure on first stripe succeeded"
24960         stack_trap "rm -f $DIR/$tfile"
24961         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24962
24963         # Place data in file for read
24964         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24965                 error "parallel dio write failed"
24966
24967         # Fail read on OST1, second stripe
24968         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24969         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24970         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24971                 error "parallel dio read with error on first stripe succeeded"
24972         rm -f $DIR/$tfile.2
24973         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24974 }
24975 run_test 398m "test RPC failures with parallel dio"
24976
24977 # Parallel submission of DIO should not cause problems for append, but it's
24978 # important to verify.
24979 test_398n() { #  LU-13798
24980         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24981
24982         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24983                 error "dd to create source file failed"
24984         stack_trap "rm -f $DIR/$tfile"
24985
24986         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24987                 error "parallel dio write with failure on second stripe succeeded"
24988         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24989         diff $DIR/$tfile $DIR/$tfile.1
24990         [[ $? == 0 ]] || error "data incorrect after append"
24991
24992 }
24993 run_test 398n "test append with parallel DIO"
24994
24995 test_fake_rw() {
24996         local read_write=$1
24997         if [ "$read_write" = "write" ]; then
24998                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24999         elif [ "$read_write" = "read" ]; then
25000                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25001         else
25002                 error "argument error"
25003         fi
25004
25005         # turn off debug for performance testing
25006         local saved_debug=$($LCTL get_param -n debug)
25007         $LCTL set_param debug=0
25008
25009         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25010
25011         # get ost1 size - $FSNAME-OST0000
25012         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25013         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25014         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25015
25016         if [ "$read_write" = "read" ]; then
25017                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25018         fi
25019
25020         local start_time=$(date +%s.%N)
25021         $dd_cmd bs=1M count=$blocks oflag=sync ||
25022                 error "real dd $read_write error"
25023         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25024
25025         if [ "$read_write" = "write" ]; then
25026                 rm -f $DIR/$tfile
25027         fi
25028
25029         # define OBD_FAIL_OST_FAKE_RW           0x238
25030         do_facet ost1 $LCTL set_param fail_loc=0x238
25031
25032         local start_time=$(date +%s.%N)
25033         $dd_cmd bs=1M count=$blocks oflag=sync ||
25034                 error "fake dd $read_write error"
25035         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25036
25037         if [ "$read_write" = "write" ]; then
25038                 # verify file size
25039                 cancel_lru_locks osc
25040                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25041                         error "$tfile size not $blocks MB"
25042         fi
25043         do_facet ost1 $LCTL set_param fail_loc=0
25044
25045         echo "fake $read_write $duration_fake vs. normal $read_write" \
25046                 "$duration in seconds"
25047         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25048                 error_not_in_vm "fake write is slower"
25049
25050         $LCTL set_param -n debug="$saved_debug"
25051         rm -f $DIR/$tfile
25052 }
25053 test_399a() { # LU-7655 for OST fake write
25054         remote_ost_nodsh && skip "remote OST with nodsh"
25055
25056         test_fake_rw write
25057 }
25058 run_test 399a "fake write should not be slower than normal write"
25059
25060 test_399b() { # LU-8726 for OST fake read
25061         remote_ost_nodsh && skip "remote OST with nodsh"
25062         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25063                 skip_env "ldiskfs only test"
25064         fi
25065
25066         test_fake_rw read
25067 }
25068 run_test 399b "fake read should not be slower than normal read"
25069
25070 test_400a() { # LU-1606, was conf-sanity test_74
25071         if ! which $CC > /dev/null 2>&1; then
25072                 skip_env "$CC is not installed"
25073         fi
25074
25075         local extra_flags=''
25076         local out=$TMP/$tfile
25077         local prefix=/usr/include/lustre
25078         local prog
25079
25080         # Oleg removes c files in his test rig so test if any c files exist
25081         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
25082                 skip_env "Needed c test files are missing"
25083
25084         if ! [[ -d $prefix ]]; then
25085                 # Assume we're running in tree and fixup the include path.
25086                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
25087                 extra_flags+=" -L$LUSTRE/utils/.lib"
25088         fi
25089
25090         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25091                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
25092                         error "client api broken"
25093         done
25094         rm -f $out
25095 }
25096 run_test 400a "Lustre client api program can compile and link"
25097
25098 test_400b() { # LU-1606, LU-5011
25099         local header
25100         local out=$TMP/$tfile
25101         local prefix=/usr/include/linux/lustre
25102
25103         # We use a hard coded prefix so that this test will not fail
25104         # when run in tree. There are headers in lustre/include/lustre/
25105         # that are not packaged (like lustre_idl.h) and have more
25106         # complicated include dependencies (like config.h and lnet/types.h).
25107         # Since this test about correct packaging we just skip them when
25108         # they don't exist (see below) rather than try to fixup cppflags.
25109
25110         if ! which $CC > /dev/null 2>&1; then
25111                 skip_env "$CC is not installed"
25112         fi
25113
25114         for header in $prefix/*.h; do
25115                 if ! [[ -f "$header" ]]; then
25116                         continue
25117                 fi
25118
25119                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25120                         continue # lustre_ioctl.h is internal header
25121                 fi
25122
25123                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
25124                         error "cannot compile '$header'"
25125         done
25126         rm -f $out
25127 }
25128 run_test 400b "packaged headers can be compiled"
25129
25130 test_401a() { #LU-7437
25131         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25132         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25133
25134         #count the number of parameters by "list_param -R"
25135         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25136         #count the number of parameters by listing proc files
25137         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25138         echo "proc_dirs='$proc_dirs'"
25139         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25140         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25141                       sort -u | wc -l)
25142
25143         [ $params -eq $procs ] ||
25144                 error "found $params parameters vs. $procs proc files"
25145
25146         # test the list_param -D option only returns directories
25147         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25148         #count the number of parameters by listing proc directories
25149         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25150                 sort -u | wc -l)
25151
25152         [ $params -eq $procs ] ||
25153                 error "found $params parameters vs. $procs proc files"
25154 }
25155 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25156
25157 test_401b() {
25158         # jobid_var may not allow arbitrary values, so use jobid_name
25159         # if available
25160         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25161                 local testname=jobid_name tmp='testing%p'
25162         else
25163                 local testname=jobid_var tmp=testing
25164         fi
25165
25166         local save=$($LCTL get_param -n $testname)
25167
25168         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25169                 error "no error returned when setting bad parameters"
25170
25171         local jobid_new=$($LCTL get_param -n foe $testname baz)
25172         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25173
25174         $LCTL set_param -n fog=bam $testname=$save bat=fog
25175         local jobid_old=$($LCTL get_param -n foe $testname bag)
25176         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25177 }
25178 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25179
25180 test_401c() {
25181         # jobid_var may not allow arbitrary values, so use jobid_name
25182         # if available
25183         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25184                 local testname=jobid_name
25185         else
25186                 local testname=jobid_var
25187         fi
25188
25189         local jobid_var_old=$($LCTL get_param -n $testname)
25190         local jobid_var_new
25191
25192         $LCTL set_param $testname= &&
25193                 error "no error returned for 'set_param a='"
25194
25195         jobid_var_new=$($LCTL get_param -n $testname)
25196         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25197                 error "$testname was changed by setting without value"
25198
25199         $LCTL set_param $testname &&
25200                 error "no error returned for 'set_param a'"
25201
25202         jobid_var_new=$($LCTL get_param -n $testname)
25203         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25204                 error "$testname was changed by setting without value"
25205 }
25206 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25207
25208 test_401d() {
25209         # jobid_var may not allow arbitrary values, so use jobid_name
25210         # if available
25211         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25212                 local testname=jobid_name new_value='foo=bar%p'
25213         else
25214                 local testname=jobid_var new_valuie=foo=bar
25215         fi
25216
25217         local jobid_var_old=$($LCTL get_param -n $testname)
25218         local jobid_var_new
25219
25220         $LCTL set_param $testname=$new_value ||
25221                 error "'set_param a=b' did not accept a value containing '='"
25222
25223         jobid_var_new=$($LCTL get_param -n $testname)
25224         [[ "$jobid_var_new" == "$new_value" ]] ||
25225                 error "'set_param a=b' failed on a value containing '='"
25226
25227         # Reset the $testname to test the other format
25228         $LCTL set_param $testname=$jobid_var_old
25229         jobid_var_new=$($LCTL get_param -n $testname)
25230         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25231                 error "failed to reset $testname"
25232
25233         $LCTL set_param $testname $new_value ||
25234                 error "'set_param a b' did not accept a value containing '='"
25235
25236         jobid_var_new=$($LCTL get_param -n $testname)
25237         [[ "$jobid_var_new" == "$new_value" ]] ||
25238                 error "'set_param a b' failed on a value containing '='"
25239
25240         $LCTL set_param $testname $jobid_var_old
25241         jobid_var_new=$($LCTL get_param -n $testname)
25242         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25243                 error "failed to reset $testname"
25244 }
25245 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25246
25247 test_401e() { # LU-14779
25248         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25249                 error "lctl list_param MGC* failed"
25250         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25251         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25252                 error "lctl get_param lru_size failed"
25253 }
25254 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25255
25256 test_402() {
25257         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25258         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25259                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25260         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25261                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25262                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25263         remote_mds_nodsh && skip "remote MDS with nodsh"
25264
25265         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25266 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25267         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25268         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25269                 echo "Touch failed - OK"
25270 }
25271 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25272
25273 test_403() {
25274         local file1=$DIR/$tfile.1
25275         local file2=$DIR/$tfile.2
25276         local tfile=$TMP/$tfile
25277
25278         rm -f $file1 $file2 $tfile
25279
25280         touch $file1
25281         ln $file1 $file2
25282
25283         # 30 sec OBD_TIMEOUT in ll_getattr()
25284         # right before populating st_nlink
25285         $LCTL set_param fail_loc=0x80001409
25286         stat -c %h $file1 > $tfile &
25287
25288         # create an alias, drop all locks and reclaim the dentry
25289         < $file2
25290         cancel_lru_locks mdc
25291         cancel_lru_locks osc
25292         sysctl -w vm.drop_caches=2
25293
25294         wait
25295
25296         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25297
25298         rm -f $tfile $file1 $file2
25299 }
25300 run_test 403 "i_nlink should not drop to zero due to aliasing"
25301
25302 test_404() { # LU-6601
25303         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25304                 skip "Need server version newer than 2.8.52"
25305         remote_mds_nodsh && skip "remote MDS with nodsh"
25306
25307         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25308                 awk '/osp .*-osc-MDT/ { print $4}')
25309
25310         local osp
25311         for osp in $mosps; do
25312                 echo "Deactivate: " $osp
25313                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25314                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25315                         awk -vp=$osp '$4 == p { print $2 }')
25316                 [ $stat = IN ] || {
25317                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25318                         error "deactivate error"
25319                 }
25320                 echo "Activate: " $osp
25321                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25322                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25323                         awk -vp=$osp '$4 == p { print $2 }')
25324                 [ $stat = UP ] || {
25325                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25326                         error "activate error"
25327                 }
25328         done
25329 }
25330 run_test 404 "validate manual {de}activated works properly for OSPs"
25331
25332 test_405() {
25333         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25334         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25335                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25336                         skip "Layout swap lock is not supported"
25337
25338         check_swap_layouts_support
25339         check_swap_layout_no_dom $DIR
25340
25341         test_mkdir $DIR/$tdir
25342         swap_lock_test -d $DIR/$tdir ||
25343                 error "One layout swap locked test failed"
25344 }
25345 run_test 405 "Various layout swap lock tests"
25346
25347 test_406() {
25348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25349         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25350         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25352         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25353                 skip "Need MDS version at least 2.8.50"
25354
25355         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25356         local test_pool=$TESTNAME
25357
25358         pool_add $test_pool || error "pool_add failed"
25359         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25360                 error "pool_add_targets failed"
25361
25362         save_layout_restore_at_exit $MOUNT
25363
25364         # parent set default stripe count only, child will stripe from both
25365         # parent and fs default
25366         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25367                 error "setstripe $MOUNT failed"
25368         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25369         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25370         for i in $(seq 10); do
25371                 local f=$DIR/$tdir/$tfile.$i
25372                 touch $f || error "touch failed"
25373                 local count=$($LFS getstripe -c $f)
25374                 [ $count -eq $OSTCOUNT ] ||
25375                         error "$f stripe count $count != $OSTCOUNT"
25376                 local offset=$($LFS getstripe -i $f)
25377                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25378                 local size=$($LFS getstripe -S $f)
25379                 [ $size -eq $((def_stripe_size * 2)) ] ||
25380                         error "$f stripe size $size != $((def_stripe_size * 2))"
25381                 local pool=$($LFS getstripe -p $f)
25382                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25383         done
25384
25385         # change fs default striping, delete parent default striping, now child
25386         # will stripe from new fs default striping only
25387         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25388                 error "change $MOUNT default stripe failed"
25389         $LFS setstripe -c 0 $DIR/$tdir ||
25390                 error "delete $tdir default stripe failed"
25391         for i in $(seq 11 20); do
25392                 local f=$DIR/$tdir/$tfile.$i
25393                 touch $f || error "touch $f failed"
25394                 local count=$($LFS getstripe -c $f)
25395                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25396                 local offset=$($LFS getstripe -i $f)
25397                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25398                 local size=$($LFS getstripe -S $f)
25399                 [ $size -eq $def_stripe_size ] ||
25400                         error "$f stripe size $size != $def_stripe_size"
25401                 local pool=$($LFS getstripe -p $f)
25402                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25403         done
25404
25405         unlinkmany $DIR/$tdir/$tfile. 1 20
25406
25407         local f=$DIR/$tdir/$tfile
25408         pool_remove_all_targets $test_pool $f
25409         pool_remove $test_pool $f
25410 }
25411 run_test 406 "DNE support fs default striping"
25412
25413 test_407() {
25414         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25415         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25416                 skip "Need MDS version at least 2.8.55"
25417         remote_mds_nodsh && skip "remote MDS with nodsh"
25418
25419         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25420                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25421         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25422                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25423         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25424
25425         #define OBD_FAIL_DT_TXN_STOP    0x2019
25426         for idx in $(seq $MDSCOUNT); do
25427                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25428         done
25429         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25430         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25431                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25432         true
25433 }
25434 run_test 407 "transaction fail should cause operation fail"
25435
25436 test_408() {
25437         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25438
25439         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25440         lctl set_param fail_loc=0x8000040a
25441         # let ll_prepare_partial_page() fail
25442         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25443
25444         rm -f $DIR/$tfile
25445
25446         # create at least 100 unused inodes so that
25447         # shrink_icache_memory(0) should not return 0
25448         touch $DIR/$tfile-{0..100}
25449         rm -f $DIR/$tfile-{0..100}
25450         sync
25451
25452         echo 2 > /proc/sys/vm/drop_caches
25453 }
25454 run_test 408 "drop_caches should not hang due to page leaks"
25455
25456 test_409()
25457 {
25458         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25459
25460         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25461         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25462         touch $DIR/$tdir/guard || error "(2) Fail to create"
25463
25464         local PREFIX=$(str_repeat 'A' 128)
25465         echo "Create 1K hard links start at $(date)"
25466         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25467                 error "(3) Fail to hard link"
25468
25469         echo "Links count should be right although linkEA overflow"
25470         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25471         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25472         [ $linkcount -eq 1001 ] ||
25473                 error "(5) Unexpected hard links count: $linkcount"
25474
25475         echo "List all links start at $(date)"
25476         ls -l $DIR/$tdir/foo > /dev/null ||
25477                 error "(6) Fail to list $DIR/$tdir/foo"
25478
25479         echo "Unlink hard links start at $(date)"
25480         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25481                 error "(7) Fail to unlink"
25482         echo "Unlink hard links finished at $(date)"
25483 }
25484 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25485
25486 test_410()
25487 {
25488         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25489                 skip "Need client version at least 2.9.59"
25490         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25491                 skip "Need MODULES build"
25492
25493         # Create a file, and stat it from the kernel
25494         local testfile=$DIR/$tfile
25495         touch $testfile
25496
25497         local run_id=$RANDOM
25498         local my_ino=$(stat --format "%i" $testfile)
25499
25500         # Try to insert the module. This will always fail as the
25501         # module is designed to not be inserted.
25502         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25503             &> /dev/null
25504
25505         # Anything but success is a test failure
25506         dmesg | grep -q \
25507             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25508             error "no inode match"
25509 }
25510 run_test 410 "Test inode number returned from kernel thread"
25511
25512 cleanup_test411_cgroup() {
25513         trap 0
25514         rmdir "$1"
25515 }
25516
25517 test_411() {
25518         local cg_basedir=/sys/fs/cgroup/memory
25519         # LU-9966
25520         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25521                 skip "no setup for cgroup"
25522
25523         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25524                 error "test file creation failed"
25525         cancel_lru_locks osc
25526
25527         # Create a very small memory cgroup to force a slab allocation error
25528         local cgdir=$cg_basedir/osc_slab_alloc
25529         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25530         trap "cleanup_test411_cgroup $cgdir" EXIT
25531         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25532         echo 1M > $cgdir/memory.limit_in_bytes
25533
25534         # Should not LBUG, just be killed by oom-killer
25535         # dd will return 0 even allocation failure in some environment.
25536         # So don't check return value
25537         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25538         cleanup_test411_cgroup $cgdir
25539
25540         return 0
25541 }
25542 run_test 411 "Slab allocation error with cgroup does not LBUG"
25543
25544 test_412() {
25545         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25546         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25547                 skip "Need server version at least 2.10.55"
25548
25549         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25550                 error "mkdir failed"
25551         $LFS getdirstripe $DIR/$tdir
25552         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25553         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25554                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25555         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25556         [ $stripe_count -eq 2 ] ||
25557                 error "expect 2 get $stripe_count"
25558
25559         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25560
25561         local index
25562         local index2
25563
25564         # subdirs should be on the same MDT as parent
25565         for i in $(seq 0 $((MDSCOUNT - 1))); do
25566                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25567                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25568                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25569                 (( index == i )) || error "mdt$i/sub on MDT$index"
25570         done
25571
25572         # stripe offset -1, ditto
25573         for i in {1..10}; do
25574                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25575                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25576                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25577                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25578                 (( index == index2 )) ||
25579                         error "qos$i on MDT$index, sub on MDT$index2"
25580         done
25581
25582         local testdir=$DIR/$tdir/inherit
25583
25584         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25585         # inherit 2 levels
25586         for i in 1 2; do
25587                 testdir=$testdir/s$i
25588                 mkdir $testdir || error "mkdir $testdir failed"
25589                 index=$($LFS getstripe -m $testdir)
25590                 (( index == 1 )) ||
25591                         error "$testdir on MDT$index"
25592         done
25593
25594         # not inherit any more
25595         testdir=$testdir/s3
25596         mkdir $testdir || error "mkdir $testdir failed"
25597         getfattr -d -m dmv $testdir | grep dmv &&
25598                 error "default LMV set on $testdir" || true
25599 }
25600 run_test 412 "mkdir on specific MDTs"
25601
25602 generate_uneven_mdts() {
25603         local threshold=$1
25604         local lmv_qos_maxage
25605         local lod_qos_maxage
25606         local ffree
25607         local bavail
25608         local max
25609         local min
25610         local max_index
25611         local min_index
25612         local tmp
25613         local i
25614
25615         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25616         $LCTL set_param lmv.*.qos_maxage=1
25617         stack_trap "$LCTL set_param \
25618                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25619         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25620                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25621         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25622                 lod.*.mdt_qos_maxage=1
25623         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25624                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25625
25626         echo
25627         echo "Check for uneven MDTs: "
25628
25629         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25630         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25631         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25632
25633         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25634         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25635         max_index=0
25636         min_index=0
25637         for ((i = 1; i < ${#ffree[@]}; i++)); do
25638                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25639                 if [ $tmp -gt $max ]; then
25640                         max=$tmp
25641                         max_index=$i
25642                 fi
25643                 if [ $tmp -lt $min ]; then
25644                         min=$tmp
25645                         min_index=$i
25646                 fi
25647         done
25648
25649         (( ${ffree[min_index]} > 0 )) ||
25650                 skip "no free files in MDT$min_index"
25651         (( ${ffree[min_index]} < 10000000 )) ||
25652                 skip "too many free files in MDT$min_index"
25653
25654         # Check if we need to generate uneven MDTs
25655         local diff=$(((max - min) * 100 / min))
25656         local testdir=$DIR/$tdir-fillmdt
25657         local start
25658
25659         mkdir -p $testdir
25660
25661         i=0
25662         while (( diff < threshold )); do
25663                 # generate uneven MDTs, create till $threshold% diff
25664                 echo -n "weight diff=$diff% must be > $threshold% ..."
25665                 echo "Fill MDT$min_index with 1000 files: loop $i"
25666                 testdir=$DIR/$tdir-fillmdt/$i
25667                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25668                         error "mkdir $testdir failed"
25669                 $LFS setstripe -E 1M -L mdt $testdir ||
25670                         error "setstripe $testdir failed"
25671                 start=$SECONDS
25672                 for F in f.{0..999}; do
25673                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25674                                 /dev/null 2>&1 || error "dd $F failed"
25675                 done
25676
25677                 # wait for QOS to update
25678                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25679
25680                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25681                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25682                 max=$(((${ffree[max_index]} >> 8) *
25683                         (${bavail[max_index]} * bsize >> 16)))
25684                 min=$(((${ffree[min_index]} >> 8) *
25685                         (${bavail[min_index]} * bsize >> 16)))
25686                 diff=$(((max - min) * 100 / min))
25687                 i=$((i + 1))
25688         done
25689
25690         echo "MDT filesfree available: ${ffree[*]}"
25691         echo "MDT blocks available: ${bavail[*]}"
25692         echo "weight diff=$diff%"
25693 }
25694
25695 test_qos_mkdir() {
25696         local mkdir_cmd=$1
25697         local stripe_count=$2
25698         local mdts=$(comma_list $(mdts_nodes))
25699
25700         local testdir
25701         local lmv_qos_prio_free
25702         local lmv_qos_threshold_rr
25703         local lmv_qos_maxage
25704         local lod_qos_prio_free
25705         local lod_qos_threshold_rr
25706         local lod_qos_maxage
25707         local count
25708         local i
25709
25710         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25711         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25712         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25713                 head -n1)
25714         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25715         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25716         stack_trap "$LCTL set_param \
25717                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25718         stack_trap "$LCTL set_param \
25719                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25720         stack_trap "$LCTL set_param \
25721                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25722
25723         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25724                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25725         lod_qos_prio_free=${lod_qos_prio_free%%%}
25726         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25727                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25728         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25729         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25730                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25731         stack_trap "do_nodes $mdts $LCTL set_param \
25732                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25733         stack_trap "do_nodes $mdts $LCTL set_param \
25734                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25735         stack_trap "do_nodes $mdts $LCTL set_param \
25736                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25737
25738         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25739         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25740
25741         testdir=$DIR/$tdir-s$stripe_count/rr
25742
25743         local stripe_index=$($LFS getstripe -m $testdir)
25744         local test_mkdir_rr=true
25745
25746         getfattr -d -m dmv -e hex $testdir | grep dmv
25747         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25748                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25749                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25750                         test_mkdir_rr=false
25751         fi
25752
25753         echo
25754         $test_mkdir_rr &&
25755                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25756                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25757
25758         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25759         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25760                 eval $mkdir_cmd $testdir/subdir$i ||
25761                         error "$mkdir_cmd subdir$i failed"
25762         done
25763
25764         for (( i = 0; i < $MDSCOUNT; i++ )); do
25765                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25766                 echo "$count directories created on MDT$i"
25767                 if $test_mkdir_rr; then
25768                         (( $count == 100 )) ||
25769                                 error "subdirs are not evenly distributed"
25770                 elif (( $i == $stripe_index )); then
25771                         (( $count == 100 * MDSCOUNT )) ||
25772                                 error "$count subdirs created on MDT$i"
25773                 else
25774                         (( $count == 0 )) ||
25775                                 error "$count subdirs created on MDT$i"
25776                 fi
25777
25778                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25779                         count=$($LFS getdirstripe $testdir/* |
25780                                 grep -c -P "^\s+$i\t")
25781                         echo "$count stripes created on MDT$i"
25782                         # deviation should < 5% of average
25783                         (( $count >= 95 * stripe_count &&
25784                            $count <= 105 * stripe_count)) ||
25785                                 error "stripes are not evenly distributed"
25786                 fi
25787         done
25788
25789         echo
25790         echo "Check for uneven MDTs: "
25791
25792         local ffree
25793         local bavail
25794         local max
25795         local min
25796         local max_index
25797         local min_index
25798         local tmp
25799
25800         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25801         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25802         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25803
25804         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25805         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25806         max_index=0
25807         min_index=0
25808         for ((i = 1; i < ${#ffree[@]}; i++)); do
25809                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25810                 if [ $tmp -gt $max ]; then
25811                         max=$tmp
25812                         max_index=$i
25813                 fi
25814                 if [ $tmp -lt $min ]; then
25815                         min=$tmp
25816                         min_index=$i
25817                 fi
25818         done
25819
25820         (( ${ffree[min_index]} > 0 )) ||
25821                 skip "no free files in MDT$min_index"
25822         (( ${ffree[min_index]} < 10000000 )) ||
25823                 skip "too many free files in MDT$min_index"
25824
25825         echo "MDT filesfree available: ${ffree[*]}"
25826         echo "MDT blocks available: ${bavail[*]}"
25827         echo "weight diff=$(((max - min) * 100 / min))%"
25828         echo
25829         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25830
25831         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25832         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25833         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25834         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25835         # decrease statfs age, so that it can be updated in time
25836         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25837         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25838
25839         sleep 1
25840
25841         testdir=$DIR/$tdir-s$stripe_count/qos
25842         local num=200
25843
25844         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25845         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25846                 eval $mkdir_cmd $testdir/subdir$i ||
25847                         error "$mkdir_cmd subdir$i failed"
25848         done
25849
25850         max=0
25851         for (( i = 0; i < $MDSCOUNT; i++ )); do
25852                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25853                 (( count > max )) && max=$count
25854                 echo "$count directories created on MDT$i"
25855         done
25856
25857         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25858
25859         # D-value should > 10% of averge
25860         (( max - min > num / 10 )) ||
25861                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25862
25863         # ditto for stripes
25864         if (( stripe_count > 1 )); then
25865                 max=0
25866                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25867                         count=$($LFS getdirstripe $testdir/* |
25868                                 grep -c -P "^\s+$i\t")
25869                         (( count > max )) && max=$count
25870                         echo "$count stripes created on MDT$i"
25871                 done
25872
25873                 min=$($LFS getdirstripe $testdir/* |
25874                         grep -c -P "^\s+$min_index\t")
25875                 (( max - min > num * stripe_count / 10 )) ||
25876                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25877         fi
25878 }
25879
25880 most_full_mdt() {
25881         local ffree
25882         local bavail
25883         local bsize
25884         local min
25885         local min_index
25886         local tmp
25887
25888         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25889         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25890         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25891
25892         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25893         min_index=0
25894         for ((i = 1; i < ${#ffree[@]}; i++)); do
25895                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25896                 (( tmp < min )) && min=$tmp && min_index=$i
25897         done
25898
25899         echo -n $min_index
25900 }
25901
25902 test_413a() {
25903         [ $MDSCOUNT -lt 2 ] &&
25904                 skip "We need at least 2 MDTs for this test"
25905
25906         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25907                 skip "Need server version at least 2.12.52"
25908
25909         local stripe_count
25910
25911         generate_uneven_mdts 100
25912         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25913                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25914                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25915                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25916                         error "mkdir failed"
25917                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25918         done
25919 }
25920 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25921
25922 test_413b() {
25923         [ $MDSCOUNT -lt 2 ] &&
25924                 skip "We need at least 2 MDTs for this test"
25925
25926         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25927                 skip "Need server version at least 2.12.52"
25928
25929         local testdir
25930         local stripe_count
25931
25932         generate_uneven_mdts 100
25933         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25934                 testdir=$DIR/$tdir-s$stripe_count
25935                 mkdir $testdir || error "mkdir $testdir failed"
25936                 mkdir $testdir/rr || error "mkdir rr failed"
25937                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25938                         error "mkdir qos failed"
25939                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25940                         $testdir/rr || error "setdirstripe rr failed"
25941                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25942                         error "setdirstripe failed"
25943                 test_qos_mkdir "mkdir" $stripe_count
25944         done
25945 }
25946 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25947
25948 test_413c() {
25949         (( $MDSCOUNT >= 2 )) ||
25950                 skip "We need at least 2 MDTs for this test"
25951
25952         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25953                 skip "Need server version at least 2.14.51"
25954
25955         local testdir
25956         local inherit
25957         local inherit_rr
25958
25959         testdir=$DIR/${tdir}-s1
25960         mkdir $testdir || error "mkdir $testdir failed"
25961         mkdir $testdir/rr || error "mkdir rr failed"
25962         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25963         # default max_inherit is -1, default max_inherit_rr is 0
25964         $LFS setdirstripe -D -c 1 $testdir/rr ||
25965                 error "setdirstripe rr failed"
25966         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25967                 error "setdirstripe qos failed"
25968         test_qos_mkdir "mkdir" 1
25969
25970         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25971         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25972         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25973         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25974         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25975
25976         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25977         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25978         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25979         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25980         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25981         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25982         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25983                 error "level2 shouldn't have default LMV" || true
25984 }
25985 run_test 413c "mkdir with default LMV max inherit rr"
25986
25987 test_413d() {
25988         (( MDSCOUNT >= 2 )) ||
25989                 skip "We need at least 2 MDTs for this test"
25990
25991         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25992                 skip "Need server version at least 2.14.51"
25993
25994         local lmv_qos_threshold_rr
25995
25996         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25997                 head -n1)
25998         stack_trap "$LCTL set_param \
25999                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26000
26001         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26002         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26003         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26004                 error "$tdir shouldn't have default LMV"
26005         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26006                 error "mkdir sub failed"
26007
26008         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26009
26010         (( count == 100 )) || error "$count subdirs on MDT0"
26011 }
26012 run_test 413d "inherit ROOT default LMV"
26013
26014 test_413e() {
26015         (( MDSCOUNT >= 2 )) ||
26016                 skip "We need at least 2 MDTs for this test"
26017         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26018                 skip "Need server version at least 2.14.55"
26019
26020         local testdir=$DIR/$tdir
26021         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26022         local max_inherit
26023         local sub_max_inherit
26024
26025         mkdir -p $testdir || error "failed to create $testdir"
26026
26027         # set default max-inherit to -1 if stripe count is 0 or 1
26028         $LFS setdirstripe -D -c 1 $testdir ||
26029                 error "failed to set default LMV"
26030         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26031         (( max_inherit == -1 )) ||
26032                 error "wrong max_inherit value $max_inherit"
26033
26034         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26035         $LFS setdirstripe -D -c -1 $testdir ||
26036                 error "failed to set default LMV"
26037         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26038         (( max_inherit > 0 )) ||
26039                 error "wrong max_inherit value $max_inherit"
26040
26041         # and the subdir will decrease the max_inherit by 1
26042         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26043         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26044         (( sub_max_inherit == max_inherit - 1)) ||
26045                 error "wrong max-inherit of subdir $sub_max_inherit"
26046
26047         # check specified --max-inherit and warning message
26048         stack_trap "rm -f $tmpfile"
26049         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26050                 error "failed to set default LMV"
26051         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26052         (( max_inherit == -1 )) ||
26053                 error "wrong max_inherit value $max_inherit"
26054
26055         # check the warning messages
26056         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26057                 error "failed to detect warning string"
26058         fi
26059 }
26060 run_test 413e "check default max-inherit value"
26061
26062 test_fs_dmv_inherit()
26063 {
26064         local testdir=$DIR/$tdir
26065
26066         local count
26067         local inherit
26068         local inherit_rr
26069
26070         for i in 1 2 3; do
26071                 mkdir $testdir || error "mkdir $testdir failed"
26072                 count=$($LFS getdirstripe -D -c $testdir)
26073                 (( count == 1 )) ||
26074                         error "$testdir default LMV count mismatch $count != 1"
26075                 inherit=$($LFS getdirstripe -D -X $testdir)
26076                 (( inherit == 3 - i )) ||
26077                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26078                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26079                 (( inherit_rr == 3 - i )) ||
26080                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26081                 testdir=$testdir/sub
26082         done
26083
26084         mkdir $testdir || error "mkdir $testdir failed"
26085         count=$($LFS getdirstripe -D -c $testdir)
26086         (( count == 0 )) ||
26087                 error "$testdir default LMV count not zero: $count"
26088 }
26089
26090 test_413f() {
26091         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26092
26093         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26094                 skip "Need server version at least 2.14.55"
26095
26096         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26097                 error "dump $DIR default LMV failed"
26098         stack_trap "setfattr --restore=$TMP/dmv.ea"
26099
26100         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26101                 error "set $DIR default LMV failed"
26102
26103         test_fs_dmv_inherit
26104 }
26105 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26106
26107 test_413g() {
26108         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26109
26110         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26111         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26112                 error "dump $DIR default LMV failed"
26113         stack_trap "setfattr --restore=$TMP/dmv.ea"
26114
26115         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26116                 error "set $DIR default LMV failed"
26117
26118         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26119                 error "mount $MOUNT2 failed"
26120         stack_trap "umount_client $MOUNT2"
26121
26122         local saved_DIR=$DIR
26123
26124         export DIR=$MOUNT2
26125
26126         stack_trap "export DIR=$saved_DIR"
26127
26128         # first check filesystem-wide default LMV inheritance
26129         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26130
26131         # then check subdirs are spread to all MDTs
26132         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26133
26134         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26135
26136         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26137 }
26138 run_test 413g "enforce ROOT default LMV on subdir mount"
26139
26140 test_413z() {
26141         local pids=""
26142         local subdir
26143         local pid
26144
26145         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26146                 unlinkmany $subdir/f. 1000 &
26147                 pids="$pids $!"
26148         done
26149
26150         for pid in $pids; do
26151                 wait $pid
26152         done
26153 }
26154 run_test 413z "413 test cleanup"
26155
26156 test_414() {
26157 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26158         $LCTL set_param fail_loc=0x80000521
26159         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26160         rm -f $DIR/$tfile
26161 }
26162 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26163
26164 test_415() {
26165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26166         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26167                 skip "Need server version at least 2.11.52"
26168
26169         # LU-11102
26170         local total
26171         local setattr_pid
26172         local start_time
26173         local end_time
26174         local duration
26175
26176         total=500
26177         # this test may be slow on ZFS
26178         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26179
26180         # though this test is designed for striped directory, let's test normal
26181         # directory too since lock is always saved as CoS lock.
26182         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26183         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26184
26185         (
26186                 while true; do
26187                         touch $DIR/$tdir
26188                 done
26189         ) &
26190         setattr_pid=$!
26191
26192         start_time=$(date +%s)
26193         for i in $(seq $total); do
26194                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26195                         > /dev/null
26196         done
26197         end_time=$(date +%s)
26198         duration=$((end_time - start_time))
26199
26200         kill -9 $setattr_pid
26201
26202         echo "rename $total files took $duration sec"
26203         [ $duration -lt 100 ] || error "rename took $duration sec"
26204 }
26205 run_test 415 "lock revoke is not missing"
26206
26207 test_416() {
26208         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26209                 skip "Need server version at least 2.11.55"
26210
26211         # define OBD_FAIL_OSD_TXN_START    0x19a
26212         do_facet mds1 lctl set_param fail_loc=0x19a
26213
26214         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26215
26216         true
26217 }
26218 run_test 416 "transaction start failure won't cause system hung"
26219
26220 cleanup_417() {
26221         trap 0
26222         do_nodes $(comma_list $(mdts_nodes)) \
26223                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26224         do_nodes $(comma_list $(mdts_nodes)) \
26225                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26226         do_nodes $(comma_list $(mdts_nodes)) \
26227                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26228 }
26229
26230 test_417() {
26231         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26232         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26233                 skip "Need MDS version at least 2.11.56"
26234
26235         trap cleanup_417 RETURN EXIT
26236
26237         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26238         do_nodes $(comma_list $(mdts_nodes)) \
26239                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26240         $LFS migrate -m 0 $DIR/$tdir.1 &&
26241                 error "migrate dir $tdir.1 should fail"
26242
26243         do_nodes $(comma_list $(mdts_nodes)) \
26244                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26245         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26246                 error "create remote dir $tdir.2 should fail"
26247
26248         do_nodes $(comma_list $(mdts_nodes)) \
26249                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26250         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26251                 error "create striped dir $tdir.3 should fail"
26252         true
26253 }
26254 run_test 417 "disable remote dir, striped dir and dir migration"
26255
26256 # Checks that the outputs of df [-i] and lfs df [-i] match
26257 #
26258 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26259 check_lfs_df() {
26260         local dir=$2
26261         local inodes
26262         local df_out
26263         local lfs_df_out
26264         local count
26265         local passed=false
26266
26267         # blocks or inodes
26268         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26269
26270         for count in {1..100}; do
26271                 do_nodes "$CLIENTS" \
26272                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26273                 sync; sleep 0.2
26274
26275                 # read the lines of interest
26276                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26277                         error "df $inodes $dir | tail -n +2 failed"
26278                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26279                         error "lfs df $inodes $dir | grep summary: failed"
26280
26281                 # skip first substrings of each output as they are different
26282                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26283                 # compare the two outputs
26284                 passed=true
26285                 #  skip "available" on MDT until LU-13997 is fixed.
26286                 #for i in {1..5}; do
26287                 for i in 1 2 4 5; do
26288                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26289                 done
26290                 $passed && break
26291         done
26292
26293         if ! $passed; then
26294                 df -P $inodes $dir
26295                 echo
26296                 lfs df $inodes $dir
26297                 error "df and lfs df $1 output mismatch: "      \
26298                       "df ${inodes}: ${df_out[*]}, "            \
26299                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26300         fi
26301 }
26302
26303 test_418() {
26304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26305
26306         local dir=$DIR/$tdir
26307         local numfiles=$((RANDOM % 4096 + 2))
26308         local numblocks=$((RANDOM % 256 + 1))
26309
26310         wait_delete_completed
26311         test_mkdir $dir
26312
26313         # check block output
26314         check_lfs_df blocks $dir
26315         # check inode output
26316         check_lfs_df inodes $dir
26317
26318         # create a single file and retest
26319         echo "Creating a single file and testing"
26320         createmany -o $dir/$tfile- 1 &>/dev/null ||
26321                 error "creating 1 file in $dir failed"
26322         check_lfs_df blocks $dir
26323         check_lfs_df inodes $dir
26324
26325         # create a random number of files
26326         echo "Creating $((numfiles - 1)) files and testing"
26327         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26328                 error "creating $((numfiles - 1)) files in $dir failed"
26329
26330         # write a random number of blocks to the first test file
26331         echo "Writing $numblocks 4K blocks and testing"
26332         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26333                 count=$numblocks &>/dev/null ||
26334                 error "dd to $dir/${tfile}-0 failed"
26335
26336         # retest
26337         check_lfs_df blocks $dir
26338         check_lfs_df inodes $dir
26339
26340         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26341                 error "unlinking $numfiles files in $dir failed"
26342 }
26343 run_test 418 "df and lfs df outputs match"
26344
26345 test_419()
26346 {
26347         local dir=$DIR/$tdir
26348
26349         mkdir -p $dir
26350         touch $dir/file
26351
26352         cancel_lru_locks mdc
26353
26354         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26355         $LCTL set_param fail_loc=0x1410
26356         cat $dir/file
26357         $LCTL set_param fail_loc=0
26358         rm -rf $dir
26359 }
26360 run_test 419 "Verify open file by name doesn't crash kernel"
26361
26362 test_420()
26363 {
26364         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26365                 skip "Need MDS version at least 2.12.53"
26366
26367         local SAVE_UMASK=$(umask)
26368         local dir=$DIR/$tdir
26369         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26370
26371         mkdir -p $dir
26372         umask 0000
26373         mkdir -m03777 $dir/testdir
26374         ls -dn $dir/testdir
26375         # Need to remove trailing '.' when SELinux is enabled
26376         local dirperms=$(ls -dn $dir/testdir |
26377                          awk '{ sub(/\.$/, "", $1); print $1}')
26378         [ $dirperms == "drwxrwsrwt" ] ||
26379                 error "incorrect perms on $dir/testdir"
26380
26381         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26382                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26383         ls -n $dir/testdir/testfile
26384         local fileperms=$(ls -n $dir/testdir/testfile |
26385                           awk '{ sub(/\.$/, "", $1); print $1}')
26386         [ $fileperms == "-rwxr-xr-x" ] ||
26387                 error "incorrect perms on $dir/testdir/testfile"
26388
26389         umask $SAVE_UMASK
26390 }
26391 run_test 420 "clear SGID bit on non-directories for non-members"
26392
26393 test_421a() {
26394         local cnt
26395         local fid1
26396         local fid2
26397
26398         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26399                 skip "Need MDS version at least 2.12.54"
26400
26401         test_mkdir $DIR/$tdir
26402         createmany -o $DIR/$tdir/f 3
26403         cnt=$(ls -1 $DIR/$tdir | wc -l)
26404         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26405
26406         fid1=$(lfs path2fid $DIR/$tdir/f1)
26407         fid2=$(lfs path2fid $DIR/$tdir/f2)
26408         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26409
26410         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26411         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26412
26413         cnt=$(ls -1 $DIR/$tdir | wc -l)
26414         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26415
26416         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26417         createmany -o $DIR/$tdir/f 3
26418         cnt=$(ls -1 $DIR/$tdir | wc -l)
26419         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26420
26421         fid1=$(lfs path2fid $DIR/$tdir/f1)
26422         fid2=$(lfs path2fid $DIR/$tdir/f2)
26423         echo "remove using fsname $FSNAME"
26424         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26425
26426         cnt=$(ls -1 $DIR/$tdir | wc -l)
26427         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26428 }
26429 run_test 421a "simple rm by fid"
26430
26431 test_421b() {
26432         local cnt
26433         local FID1
26434         local FID2
26435
26436         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26437                 skip "Need MDS version at least 2.12.54"
26438
26439         test_mkdir $DIR/$tdir
26440         createmany -o $DIR/$tdir/f 3
26441         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26442         MULTIPID=$!
26443
26444         FID1=$(lfs path2fid $DIR/$tdir/f1)
26445         FID2=$(lfs path2fid $DIR/$tdir/f2)
26446         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26447
26448         kill -USR1 $MULTIPID
26449         wait
26450
26451         cnt=$(ls $DIR/$tdir | wc -l)
26452         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26453 }
26454 run_test 421b "rm by fid on open file"
26455
26456 test_421c() {
26457         local cnt
26458         local FIDS
26459
26460         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26461                 skip "Need MDS version at least 2.12.54"
26462
26463         test_mkdir $DIR/$tdir
26464         createmany -o $DIR/$tdir/f 3
26465         touch $DIR/$tdir/$tfile
26466         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26467         cnt=$(ls -1 $DIR/$tdir | wc -l)
26468         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26469
26470         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26471         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26472
26473         cnt=$(ls $DIR/$tdir | wc -l)
26474         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26475 }
26476 run_test 421c "rm by fid against hardlinked files"
26477
26478 test_421d() {
26479         local cnt
26480         local FIDS
26481
26482         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26483                 skip "Need MDS version at least 2.12.54"
26484
26485         test_mkdir $DIR/$tdir
26486         createmany -o $DIR/$tdir/f 4097
26487         cnt=$(ls -1 $DIR/$tdir | wc -l)
26488         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26489
26490         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26491         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26492
26493         cnt=$(ls $DIR/$tdir | wc -l)
26494         rm -rf $DIR/$tdir
26495         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26496 }
26497 run_test 421d "rmfid en masse"
26498
26499 test_421e() {
26500         local cnt
26501         local FID
26502
26503         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26504         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26505                 skip "Need MDS version at least 2.12.54"
26506
26507         mkdir -p $DIR/$tdir
26508         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26509         createmany -o $DIR/$tdir/striped_dir/f 512
26510         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26511         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26512
26513         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26514                 sed "s/[/][^:]*://g")
26515         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26516
26517         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26518         rm -rf $DIR/$tdir
26519         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26520 }
26521 run_test 421e "rmfid in DNE"
26522
26523 test_421f() {
26524         local cnt
26525         local FID
26526
26527         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26528                 skip "Need MDS version at least 2.12.54"
26529
26530         test_mkdir $DIR/$tdir
26531         touch $DIR/$tdir/f
26532         cnt=$(ls -1 $DIR/$tdir | wc -l)
26533         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26534
26535         FID=$(lfs path2fid $DIR/$tdir/f)
26536         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26537         # rmfid should fail
26538         cnt=$(ls -1 $DIR/$tdir | wc -l)
26539         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26540
26541         chmod a+rw $DIR/$tdir
26542         ls -la $DIR/$tdir
26543         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26544         # rmfid should fail
26545         cnt=$(ls -1 $DIR/$tdir | wc -l)
26546         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26547
26548         rm -f $DIR/$tdir/f
26549         $RUNAS touch $DIR/$tdir/f
26550         FID=$(lfs path2fid $DIR/$tdir/f)
26551         echo "rmfid as root"
26552         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26553         cnt=$(ls -1 $DIR/$tdir | wc -l)
26554         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26555
26556         rm -f $DIR/$tdir/f
26557         $RUNAS touch $DIR/$tdir/f
26558         cnt=$(ls -1 $DIR/$tdir | wc -l)
26559         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26560         FID=$(lfs path2fid $DIR/$tdir/f)
26561         # rmfid w/o user_fid2path mount option should fail
26562         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26563         cnt=$(ls -1 $DIR/$tdir | wc -l)
26564         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26565
26566         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26567         stack_trap "rmdir $tmpdir"
26568         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26569                 error "failed to mount client'"
26570         stack_trap "umount_client $tmpdir"
26571
26572         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26573         # rmfid should succeed
26574         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26575         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26576
26577         # rmfid shouldn't allow to remove files due to dir's permission
26578         chmod a+rwx $tmpdir/$tdir
26579         touch $tmpdir/$tdir/f
26580         ls -la $tmpdir/$tdir
26581         FID=$(lfs path2fid $tmpdir/$tdir/f)
26582         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26583         return 0
26584 }
26585 run_test 421f "rmfid checks permissions"
26586
26587 test_421g() {
26588         local cnt
26589         local FIDS
26590
26591         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26592         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26593                 skip "Need MDS version at least 2.12.54"
26594
26595         mkdir -p $DIR/$tdir
26596         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26597         createmany -o $DIR/$tdir/striped_dir/f 512
26598         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26599         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26600
26601         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26602                 sed "s/[/][^:]*://g")
26603
26604         rm -f $DIR/$tdir/striped_dir/f1*
26605         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26606         removed=$((512 - cnt))
26607
26608         # few files have been just removed, so we expect
26609         # rmfid to fail on their fids
26610         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26611         [ $removed != $errors ] && error "$errors != $removed"
26612
26613         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26614         rm -rf $DIR/$tdir
26615         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26616 }
26617 run_test 421g "rmfid to return errors properly"
26618
26619 test_422() {
26620         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26621         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26622         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26623         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26624         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26625
26626         local amc=$(at_max_get client)
26627         local amo=$(at_max_get mds1)
26628         local timeout=`lctl get_param -n timeout`
26629
26630         at_max_set 0 client
26631         at_max_set 0 mds1
26632
26633 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26634         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26635                         fail_val=$(((2*timeout + 10)*1000))
26636         touch $DIR/$tdir/d3/file &
26637         sleep 2
26638 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26639         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26640                         fail_val=$((2*timeout + 5))
26641         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26642         local pid=$!
26643         sleep 1
26644         kill -9 $pid
26645         sleep $((2 * timeout))
26646         echo kill $pid
26647         kill -9 $pid
26648         lctl mark touch
26649         touch $DIR/$tdir/d2/file3
26650         touch $DIR/$tdir/d2/file4
26651         touch $DIR/$tdir/d2/file5
26652
26653         wait
26654         at_max_set $amc client
26655         at_max_set $amo mds1
26656
26657         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26658         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26659                 error "Watchdog is always throttled"
26660 }
26661 run_test 422 "kill a process with RPC in progress"
26662
26663 stat_test() {
26664     df -h $MOUNT &
26665     df -h $MOUNT &
26666     df -h $MOUNT &
26667     df -h $MOUNT &
26668     df -h $MOUNT &
26669     df -h $MOUNT &
26670 }
26671
26672 test_423() {
26673     local _stats
26674     # ensure statfs cache is expired
26675     sleep 2;
26676
26677     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26678     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26679
26680     return 0
26681 }
26682 run_test 423 "statfs should return a right data"
26683
26684 test_424() {
26685 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26686         $LCTL set_param fail_loc=0x80000522
26687         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26688         rm -f $DIR/$tfile
26689 }
26690 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26691
26692 test_425() {
26693         test_mkdir -c -1 $DIR/$tdir
26694         $LFS setstripe -c -1 $DIR/$tdir
26695
26696         lru_resize_disable "" 100
26697         stack_trap "lru_resize_enable" EXIT
26698
26699         sleep 5
26700
26701         for i in $(seq $((MDSCOUNT * 125))); do
26702                 local t=$DIR/$tdir/$tfile_$i
26703
26704                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26705                         error_noexit "Create file $t"
26706         done
26707         stack_trap "rm -rf $DIR/$tdir" EXIT
26708
26709         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26710                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26711                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26712
26713                 [ $lock_count -le $lru_size ] ||
26714                         error "osc lock count $lock_count > lru size $lru_size"
26715         done
26716
26717         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26718                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26719                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26720
26721                 [ $lock_count -le $lru_size ] ||
26722                         error "mdc lock count $lock_count > lru size $lru_size"
26723         done
26724 }
26725 run_test 425 "lock count should not exceed lru size"
26726
26727 test_426() {
26728         splice-test -r $DIR/$tfile
26729         splice-test -rd $DIR/$tfile
26730         splice-test $DIR/$tfile
26731         splice-test -d $DIR/$tfile
26732 }
26733 run_test 426 "splice test on Lustre"
26734
26735 test_427() {
26736         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26737         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26738                 skip "Need MDS version at least 2.12.4"
26739         local log
26740
26741         mkdir $DIR/$tdir
26742         mkdir $DIR/$tdir/1
26743         mkdir $DIR/$tdir/2
26744         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26745         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26746
26747         $LFS getdirstripe $DIR/$tdir/1/dir
26748
26749         #first setfattr for creating updatelog
26750         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26751
26752 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26753         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26754         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26755         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26756
26757         sleep 2
26758         fail mds2
26759         wait_recovery_complete mds2 $((2*TIMEOUT))
26760
26761         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26762         echo $log | grep "get update log failed" &&
26763                 error "update log corruption is detected" || true
26764 }
26765 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26766
26767 test_428() {
26768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26769         local cache_limit=$CACHE_MAX
26770
26771         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26772         $LCTL set_param -n llite.*.max_cached_mb=64
26773
26774         mkdir $DIR/$tdir
26775         $LFS setstripe -c 1 $DIR/$tdir
26776         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26777         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26778         #test write
26779         for f in $(seq 4); do
26780                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26781         done
26782         wait
26783
26784         cancel_lru_locks osc
26785         # Test read
26786         for f in $(seq 4); do
26787                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26788         done
26789         wait
26790 }
26791 run_test 428 "large block size IO should not hang"
26792
26793 test_429() { # LU-7915 / LU-10948
26794         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26795         local testfile=$DIR/$tfile
26796         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26797         local new_flag=1
26798         local first_rpc
26799         local second_rpc
26800         local third_rpc
26801
26802         $LCTL get_param $ll_opencache_threshold_count ||
26803                 skip "client does not have opencache parameter"
26804
26805         set_opencache $new_flag
26806         stack_trap "restore_opencache"
26807         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26808                 error "enable opencache failed"
26809         touch $testfile
26810         # drop MDC DLM locks
26811         cancel_lru_locks mdc
26812         # clear MDC RPC stats counters
26813         $LCTL set_param $mdc_rpcstats=clear
26814
26815         # According to the current implementation, we need to run 3 times
26816         # open & close file to verify if opencache is enabled correctly.
26817         # 1st, RPCs are sent for lookup/open and open handle is released on
26818         #      close finally.
26819         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26820         #      so open handle won't be released thereafter.
26821         # 3rd, No RPC is sent out.
26822         $MULTIOP $testfile oc || error "multiop failed"
26823         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26824         echo "1st: $first_rpc RPCs in flight"
26825
26826         $MULTIOP $testfile oc || error "multiop failed"
26827         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26828         echo "2nd: $second_rpc RPCs in flight"
26829
26830         $MULTIOP $testfile oc || error "multiop failed"
26831         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26832         echo "3rd: $third_rpc RPCs in flight"
26833
26834         #verify no MDC RPC is sent
26835         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26836 }
26837 run_test 429 "verify if opencache flag on client side does work"
26838
26839 lseek_test_430() {
26840         local offset
26841         local file=$1
26842
26843         # data at [200K, 400K)
26844         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26845                 error "256K->512K dd fails"
26846         # data at [2M, 3M)
26847         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26848                 error "2M->3M dd fails"
26849         # data at [4M, 5M)
26850         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26851                 error "4M->5M dd fails"
26852         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26853         # start at first component hole #1
26854         printf "Seeking hole from 1000 ... "
26855         offset=$(lseek_test -l 1000 $file)
26856         echo $offset
26857         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26858         printf "Seeking data from 1000 ... "
26859         offset=$(lseek_test -d 1000 $file)
26860         echo $offset
26861         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26862
26863         # start at first component data block
26864         printf "Seeking hole from 300000 ... "
26865         offset=$(lseek_test -l 300000 $file)
26866         echo $offset
26867         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26868         printf "Seeking data from 300000 ... "
26869         offset=$(lseek_test -d 300000 $file)
26870         echo $offset
26871         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26872
26873         # start at the first component but beyond end of object size
26874         printf "Seeking hole from 1000000 ... "
26875         offset=$(lseek_test -l 1000000 $file)
26876         echo $offset
26877         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26878         printf "Seeking data from 1000000 ... "
26879         offset=$(lseek_test -d 1000000 $file)
26880         echo $offset
26881         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26882
26883         # start at second component stripe 2 (empty file)
26884         printf "Seeking hole from 1500000 ... "
26885         offset=$(lseek_test -l 1500000 $file)
26886         echo $offset
26887         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26888         printf "Seeking data from 1500000 ... "
26889         offset=$(lseek_test -d 1500000 $file)
26890         echo $offset
26891         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26892
26893         # start at second component stripe 1 (all data)
26894         printf "Seeking hole from 3000000 ... "
26895         offset=$(lseek_test -l 3000000 $file)
26896         echo $offset
26897         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26898         printf "Seeking data from 3000000 ... "
26899         offset=$(lseek_test -d 3000000 $file)
26900         echo $offset
26901         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26902
26903         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26904                 error "2nd dd fails"
26905         echo "Add data block at 640K...1280K"
26906
26907         # start at before new data block, in hole
26908         printf "Seeking hole from 600000 ... "
26909         offset=$(lseek_test -l 600000 $file)
26910         echo $offset
26911         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26912         printf "Seeking data from 600000 ... "
26913         offset=$(lseek_test -d 600000 $file)
26914         echo $offset
26915         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26916
26917         # start at the first component new data block
26918         printf "Seeking hole from 1000000 ... "
26919         offset=$(lseek_test -l 1000000 $file)
26920         echo $offset
26921         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26922         printf "Seeking data from 1000000 ... "
26923         offset=$(lseek_test -d 1000000 $file)
26924         echo $offset
26925         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26926
26927         # start at second component stripe 2, new data
26928         printf "Seeking hole from 1200000 ... "
26929         offset=$(lseek_test -l 1200000 $file)
26930         echo $offset
26931         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26932         printf "Seeking data from 1200000 ... "
26933         offset=$(lseek_test -d 1200000 $file)
26934         echo $offset
26935         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26936
26937         # start beyond file end
26938         printf "Using offset > filesize ... "
26939         lseek_test -l 4000000 $file && error "lseek should fail"
26940         printf "Using offset > filesize ... "
26941         lseek_test -d 4000000 $file && error "lseek should fail"
26942
26943         printf "Done\n\n"
26944 }
26945
26946 test_430a() {
26947         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26948                 skip "MDT does not support SEEK_HOLE"
26949
26950         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26951                 skip "OST does not support SEEK_HOLE"
26952
26953         local file=$DIR/$tdir/$tfile
26954
26955         mkdir -p $DIR/$tdir
26956
26957         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26958         # OST stripe #1 will have continuous data at [1M, 3M)
26959         # OST stripe #2 is empty
26960         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26961         lseek_test_430 $file
26962         rm $file
26963         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26964         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26965         lseek_test_430 $file
26966         rm $file
26967         $LFS setstripe -c2 -S 512K $file
26968         echo "Two stripes, stripe size 512K"
26969         lseek_test_430 $file
26970         rm $file
26971         # FLR with stale mirror
26972         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26973                        -N -c2 -S 1M $file
26974         echo "Mirrored file:"
26975         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26976         echo "Plain 2 stripes 1M"
26977         lseek_test_430 $file
26978         rm $file
26979 }
26980 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26981
26982 test_430b() {
26983         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26984                 skip "OST does not support SEEK_HOLE"
26985
26986         local offset
26987         local file=$DIR/$tdir/$tfile
26988
26989         mkdir -p $DIR/$tdir
26990         # Empty layout lseek should fail
26991         $MCREATE $file
26992         # seek from 0
26993         printf "Seeking hole from 0 ... "
26994         lseek_test -l 0 $file && error "lseek should fail"
26995         printf "Seeking data from 0 ... "
26996         lseek_test -d 0 $file && error "lseek should fail"
26997         rm $file
26998
26999         # 1M-hole file
27000         $LFS setstripe -E 1M -c2 -E eof $file
27001         $TRUNCATE $file 1048576
27002         printf "Seeking hole from 1000000 ... "
27003         offset=$(lseek_test -l 1000000 $file)
27004         echo $offset
27005         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27006         printf "Seeking data from 1000000 ... "
27007         lseek_test -d 1000000 $file && error "lseek should fail"
27008         rm $file
27009
27010         # full component followed by non-inited one
27011         $LFS setstripe -E 1M -c2 -E eof $file
27012         dd if=/dev/urandom of=$file bs=1M count=1
27013         printf "Seeking hole from 1000000 ... "
27014         offset=$(lseek_test -l 1000000 $file)
27015         echo $offset
27016         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27017         printf "Seeking hole from 1048576 ... "
27018         lseek_test -l 1048576 $file && error "lseek should fail"
27019         # init second component and truncate back
27020         echo "123" >> $file
27021         $TRUNCATE $file 1048576
27022         printf "Seeking hole from 1000000 ... "
27023         offset=$(lseek_test -l 1000000 $file)
27024         echo $offset
27025         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27026         printf "Seeking hole from 1048576 ... "
27027         lseek_test -l 1048576 $file && error "lseek should fail"
27028         # boundary checks for big values
27029         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27030         offset=$(lseek_test -d 0 $file.10g)
27031         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27032         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27033         offset=$(lseek_test -d 0 $file.100g)
27034         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27035         return 0
27036 }
27037 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27038
27039 test_430c() {
27040         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27041                 skip "OST does not support SEEK_HOLE"
27042
27043         local file=$DIR/$tdir/$tfile
27044         local start
27045
27046         mkdir -p $DIR/$tdir
27047         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27048
27049         # cp version 8.33+ prefers lseek over fiemap
27050         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27051                 start=$SECONDS
27052                 time cp $file /dev/null
27053                 (( SECONDS - start < 5 )) ||
27054                         error "cp: too long runtime $((SECONDS - start))"
27055
27056         fi
27057         # tar version 1.29+ supports SEEK_HOLE/DATA
27058         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27059                 start=$SECONDS
27060                 time tar cS $file - | cat > /dev/null
27061                 (( SECONDS - start < 5 )) ||
27062                         error "tar: too long runtime $((SECONDS - start))"
27063         fi
27064 }
27065 run_test 430c "lseek: external tools check"
27066
27067 test_431() { # LU-14187
27068         local file=$DIR/$tdir/$tfile
27069
27070         mkdir -p $DIR/$tdir
27071         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27072         dd if=/dev/urandom of=$file bs=4k count=1
27073         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27074         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27075         #define OBD_FAIL_OST_RESTART_IO 0x251
27076         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27077         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27078         cp $file $file.0
27079         cancel_lru_locks
27080         sync_all_data
27081         echo 3 > /proc/sys/vm/drop_caches
27082         diff  $file $file.0 || error "data diff"
27083 }
27084 run_test 431 "Restart transaction for IO"
27085
27086 cleanup_test_432() {
27087         do_facet mgs $LCTL nodemap_activate 0
27088         wait_nm_sync active
27089 }
27090
27091 test_432() {
27092         local tmpdir=$TMP/dir432
27093
27094         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27095                 skip "Need MDS version at least 2.14.52"
27096
27097         stack_trap cleanup_test_432 EXIT
27098         mkdir $DIR/$tdir
27099         mkdir $tmpdir
27100
27101         do_facet mgs $LCTL nodemap_activate 1
27102         wait_nm_sync active
27103         do_facet mgs $LCTL nodemap_modify --name default \
27104                 --property admin --value 1
27105         do_facet mgs $LCTL nodemap_modify --name default \
27106                 --property trusted --value 1
27107         cancel_lru_locks mdc
27108         wait_nm_sync default admin_nodemap
27109         wait_nm_sync default trusted_nodemap
27110
27111         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27112                grep -ci "Operation not permitted") -ne 0 ]; then
27113                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27114         fi
27115 }
27116 run_test 432 "mv dir from outside Lustre"
27117
27118 test_433() {
27119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27120
27121         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27122                 skip "inode cache not supported"
27123
27124         $LCTL set_param llite.*.inode_cache=0
27125         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27126
27127         local count=256
27128         local before
27129         local after
27130
27131         cancel_lru_locks mdc
27132         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27133         createmany -m $DIR/$tdir/f $count
27134         createmany -d $DIR/$tdir/d $count
27135         ls -l $DIR/$tdir > /dev/null
27136         stack_trap "rm -rf $DIR/$tdir"
27137
27138         before=$(num_objects)
27139         cancel_lru_locks mdc
27140         after=$(num_objects)
27141
27142         # sometimes even @before is less than 2 * count
27143         while (( before - after < count )); do
27144                 sleep 1
27145                 after=$(num_objects)
27146                 wait=$((wait + 1))
27147                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27148                 if (( wait > 60 )); then
27149                         error "inode slab grew from $before to $after"
27150                 fi
27151         done
27152
27153         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27154 }
27155 run_test 433 "ldlm lock cancel releases dentries and inodes"
27156
27157 prep_801() {
27158         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27159         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27160                 skip "Need server version at least 2.9.55"
27161
27162         start_full_debug_logging
27163 }
27164
27165 post_801() {
27166         stop_full_debug_logging
27167 }
27168
27169 barrier_stat() {
27170         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27171                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27172                            awk '/The barrier for/ { print $7 }')
27173                 echo $st
27174         else
27175                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27176                 echo \'$st\'
27177         fi
27178 }
27179
27180 barrier_expired() {
27181         local expired
27182
27183         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27184                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27185                           awk '/will be expired/ { print $7 }')
27186         else
27187                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27188         fi
27189
27190         echo $expired
27191 }
27192
27193 test_801a() {
27194         prep_801
27195
27196         echo "Start barrier_freeze at: $(date)"
27197         #define OBD_FAIL_BARRIER_DELAY          0x2202
27198         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27199         # Do not reduce barrier time - See LU-11873
27200         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27201
27202         sleep 2
27203         local b_status=$(barrier_stat)
27204         echo "Got barrier status at: $(date)"
27205         [ "$b_status" = "'freezing_p1'" ] ||
27206                 error "(1) unexpected barrier status $b_status"
27207
27208         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27209         wait
27210         b_status=$(barrier_stat)
27211         [ "$b_status" = "'frozen'" ] ||
27212                 error "(2) unexpected barrier status $b_status"
27213
27214         local expired=$(barrier_expired)
27215         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27216         sleep $((expired + 3))
27217
27218         b_status=$(barrier_stat)
27219         [ "$b_status" = "'expired'" ] ||
27220                 error "(3) unexpected barrier status $b_status"
27221
27222         # Do not reduce barrier time - See LU-11873
27223         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27224                 error "(4) fail to freeze barrier"
27225
27226         b_status=$(barrier_stat)
27227         [ "$b_status" = "'frozen'" ] ||
27228                 error "(5) unexpected barrier status $b_status"
27229
27230         echo "Start barrier_thaw at: $(date)"
27231         #define OBD_FAIL_BARRIER_DELAY          0x2202
27232         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27233         do_facet mgs $LCTL barrier_thaw $FSNAME &
27234
27235         sleep 2
27236         b_status=$(barrier_stat)
27237         echo "Got barrier status at: $(date)"
27238         [ "$b_status" = "'thawing'" ] ||
27239                 error "(6) unexpected barrier status $b_status"
27240
27241         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27242         wait
27243         b_status=$(barrier_stat)
27244         [ "$b_status" = "'thawed'" ] ||
27245                 error "(7) unexpected barrier status $b_status"
27246
27247         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27248         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27249         do_facet mgs $LCTL barrier_freeze $FSNAME
27250
27251         b_status=$(barrier_stat)
27252         [ "$b_status" = "'failed'" ] ||
27253                 error "(8) unexpected barrier status $b_status"
27254
27255         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27256         do_facet mgs $LCTL barrier_thaw $FSNAME
27257
27258         post_801
27259 }
27260 run_test 801a "write barrier user interfaces and stat machine"
27261
27262 test_801b() {
27263         prep_801
27264
27265         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27266         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27267         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27268         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27269         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27270
27271         cancel_lru_locks mdc
27272
27273         # 180 seconds should be long enough
27274         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27275
27276         local b_status=$(barrier_stat)
27277         [ "$b_status" = "'frozen'" ] ||
27278                 error "(6) unexpected barrier status $b_status"
27279
27280         mkdir $DIR/$tdir/d0/d10 &
27281         mkdir_pid=$!
27282
27283         touch $DIR/$tdir/d1/f13 &
27284         touch_pid=$!
27285
27286         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27287         ln_pid=$!
27288
27289         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27290         mv_pid=$!
27291
27292         rm -f $DIR/$tdir/d4/f12 &
27293         rm_pid=$!
27294
27295         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27296
27297         # To guarantee taht the 'stat' is not blocked
27298         b_status=$(barrier_stat)
27299         [ "$b_status" = "'frozen'" ] ||
27300                 error "(8) unexpected barrier status $b_status"
27301
27302         # let above commands to run at background
27303         sleep 5
27304
27305         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27306         ps -p $touch_pid || error "(10) touch should be blocked"
27307         ps -p $ln_pid || error "(11) link should be blocked"
27308         ps -p $mv_pid || error "(12) rename should be blocked"
27309         ps -p $rm_pid || error "(13) unlink should be blocked"
27310
27311         b_status=$(barrier_stat)
27312         [ "$b_status" = "'frozen'" ] ||
27313                 error "(14) unexpected barrier status $b_status"
27314
27315         do_facet mgs $LCTL barrier_thaw $FSNAME
27316         b_status=$(barrier_stat)
27317         [ "$b_status" = "'thawed'" ] ||
27318                 error "(15) unexpected barrier status $b_status"
27319
27320         wait $mkdir_pid || error "(16) mkdir should succeed"
27321         wait $touch_pid || error "(17) touch should succeed"
27322         wait $ln_pid || error "(18) link should succeed"
27323         wait $mv_pid || error "(19) rename should succeed"
27324         wait $rm_pid || error "(20) unlink should succeed"
27325
27326         post_801
27327 }
27328 run_test 801b "modification will be blocked by write barrier"
27329
27330 test_801c() {
27331         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27332
27333         prep_801
27334
27335         stop mds2 || error "(1) Fail to stop mds2"
27336
27337         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27338
27339         local b_status=$(barrier_stat)
27340         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27341                 do_facet mgs $LCTL barrier_thaw $FSNAME
27342                 error "(2) unexpected barrier status $b_status"
27343         }
27344
27345         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27346                 error "(3) Fail to rescan barrier bitmap"
27347
27348         # Do not reduce barrier time - See LU-11873
27349         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27350
27351         b_status=$(barrier_stat)
27352         [ "$b_status" = "'frozen'" ] ||
27353                 error "(4) unexpected barrier status $b_status"
27354
27355         do_facet mgs $LCTL barrier_thaw $FSNAME
27356         b_status=$(barrier_stat)
27357         [ "$b_status" = "'thawed'" ] ||
27358                 error "(5) unexpected barrier status $b_status"
27359
27360         local devname=$(mdsdevname 2)
27361
27362         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27363
27364         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27365                 error "(7) Fail to rescan barrier bitmap"
27366
27367         post_801
27368 }
27369 run_test 801c "rescan barrier bitmap"
27370
27371 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27372 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27373 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27374 saved_MOUNT_OPTS=$MOUNT_OPTS
27375
27376 cleanup_802a() {
27377         trap 0
27378
27379         stopall
27380         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27381         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27382         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27383         MOUNT_OPTS=$saved_MOUNT_OPTS
27384         setupall
27385 }
27386
27387 test_802a() {
27388         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27389         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27390         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27391                 skip "Need server version at least 2.9.55"
27392
27393         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27394
27395         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27396
27397         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27398                 error "(2) Fail to copy"
27399
27400         trap cleanup_802a EXIT
27401
27402         # sync by force before remount as readonly
27403         sync; sync_all_data; sleep 3; sync_all_data
27404
27405         stopall
27406
27407         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27408         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27409         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27410
27411         echo "Mount the server as read only"
27412         setupall server_only || error "(3) Fail to start servers"
27413
27414         echo "Mount client without ro should fail"
27415         mount_client $MOUNT &&
27416                 error "(4) Mount client without 'ro' should fail"
27417
27418         echo "Mount client with ro should succeed"
27419         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27420         mount_client $MOUNT ||
27421                 error "(5) Mount client with 'ro' should succeed"
27422
27423         echo "Modify should be refused"
27424         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27425
27426         echo "Read should be allowed"
27427         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27428                 error "(7) Read should succeed under ro mode"
27429
27430         cleanup_802a
27431 }
27432 run_test 802a "simulate readonly device"
27433
27434 test_802b() {
27435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27436         remote_mds_nodsh && skip "remote MDS with nodsh"
27437
27438         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27439                 skip "readonly option not available"
27440
27441         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27442
27443         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27444                 error "(2) Fail to copy"
27445
27446         # write back all cached data before setting MDT to readonly
27447         cancel_lru_locks
27448         sync_all_data
27449
27450         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27451         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27452
27453         echo "Modify should be refused"
27454         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27455
27456         echo "Read should be allowed"
27457         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27458                 error "(7) Read should succeed under ro mode"
27459
27460         # disable readonly
27461         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27462 }
27463 run_test 802b "be able to set MDTs to readonly"
27464
27465 test_803a() {
27466         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27467         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27468                 skip "MDS needs to be newer than 2.10.54"
27469
27470         mkdir_on_mdt0 $DIR/$tdir
27471         # Create some objects on all MDTs to trigger related logs objects
27472         for idx in $(seq $MDSCOUNT); do
27473                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27474                         $DIR/$tdir/dir${idx} ||
27475                         error "Fail to create $DIR/$tdir/dir${idx}"
27476         done
27477
27478         sync; sleep 3
27479         wait_delete_completed # ensure old test cleanups are finished
27480         echo "before create:"
27481         $LFS df -i $MOUNT
27482         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27483
27484         for i in {1..10}; do
27485                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27486                         error "Fail to create $DIR/$tdir/foo$i"
27487         done
27488
27489         sync; sleep 3
27490         echo "after create:"
27491         $LFS df -i $MOUNT
27492         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27493
27494         # allow for an llog to be cleaned up during the test
27495         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27496                 error "before ($before_used) + 10 > after ($after_used)"
27497
27498         for i in {1..10}; do
27499                 rm -rf $DIR/$tdir/foo$i ||
27500                         error "Fail to remove $DIR/$tdir/foo$i"
27501         done
27502
27503         sleep 3 # avoid MDT return cached statfs
27504         wait_delete_completed
27505         echo "after unlink:"
27506         $LFS df -i $MOUNT
27507         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27508
27509         # allow for an llog to be created during the test
27510         [ $after_used -le $((before_used + 1)) ] ||
27511                 error "after ($after_used) > before ($before_used) + 1"
27512 }
27513 run_test 803a "verify agent object for remote object"
27514
27515 test_803b() {
27516         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27517         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27518                 skip "MDS needs to be newer than 2.13.56"
27519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27520
27521         for i in $(seq 0 $((MDSCOUNT - 1))); do
27522                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27523         done
27524
27525         local before=0
27526         local after=0
27527
27528         local tmp
27529
27530         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27531         for i in $(seq 0 $((MDSCOUNT - 1))); do
27532                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27533                         awk '/getattr/ { print $2 }')
27534                 before=$((before + tmp))
27535         done
27536         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27537         for i in $(seq 0 $((MDSCOUNT - 1))); do
27538                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27539                         awk '/getattr/ { print $2 }')
27540                 after=$((after + tmp))
27541         done
27542
27543         [ $before -eq $after ] || error "getattr count $before != $after"
27544 }
27545 run_test 803b "remote object can getattr from cache"
27546
27547 test_804() {
27548         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27549         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27550                 skip "MDS needs to be newer than 2.10.54"
27551         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27552
27553         mkdir -p $DIR/$tdir
27554         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27555                 error "Fail to create $DIR/$tdir/dir0"
27556
27557         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27558         local dev=$(mdsdevname 2)
27559
27560         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27561                 grep ${fid} || error "NOT found agent entry for dir0"
27562
27563         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27564                 error "Fail to create $DIR/$tdir/dir1"
27565
27566         touch $DIR/$tdir/dir1/foo0 ||
27567                 error "Fail to create $DIR/$tdir/dir1/foo0"
27568         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27569         local rc=0
27570
27571         for idx in $(seq $MDSCOUNT); do
27572                 dev=$(mdsdevname $idx)
27573                 do_facet mds${idx} \
27574                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27575                         grep ${fid} && rc=$idx
27576         done
27577
27578         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27579                 error "Fail to rename foo0 to foo1"
27580         if [ $rc -eq 0 ]; then
27581                 for idx in $(seq $MDSCOUNT); do
27582                         dev=$(mdsdevname $idx)
27583                         do_facet mds${idx} \
27584                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27585                         grep ${fid} && rc=$idx
27586                 done
27587         fi
27588
27589         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27590                 error "Fail to rename foo1 to foo2"
27591         if [ $rc -eq 0 ]; then
27592                 for idx in $(seq $MDSCOUNT); do
27593                         dev=$(mdsdevname $idx)
27594                         do_facet mds${idx} \
27595                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27596                         grep ${fid} && rc=$idx
27597                 done
27598         fi
27599
27600         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27601
27602         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27603                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27604         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27605                 error "Fail to rename foo2 to foo0"
27606         unlink $DIR/$tdir/dir1/foo0 ||
27607                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27608         rm -rf $DIR/$tdir/dir0 ||
27609                 error "Fail to rm $DIR/$tdir/dir0"
27610
27611         for idx in $(seq $MDSCOUNT); do
27612                 rc=0
27613
27614                 stop mds${idx}
27615                 dev=$(mdsdevname $idx)
27616                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27617                         rc=$?
27618                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27619                         error "mount mds$idx failed"
27620                 df $MOUNT > /dev/null 2>&1
27621
27622                 # e2fsck should not return error
27623                 [ $rc -eq 0 ] ||
27624                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27625         done
27626 }
27627 run_test 804 "verify agent entry for remote entry"
27628
27629 cleanup_805() {
27630         do_facet $SINGLEMDS zfs set quota=$old $fsset
27631         unlinkmany $DIR/$tdir/f- 1000000
27632         trap 0
27633 }
27634
27635 test_805() {
27636         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27637         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27638         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27639                 skip "netfree not implemented before 0.7"
27640         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27641                 skip "Need MDS version at least 2.10.57"
27642
27643         local fsset
27644         local freekb
27645         local usedkb
27646         local old
27647         local quota
27648         local pref="osd-zfs.$FSNAME-MDT0000."
27649
27650         # limit available space on MDS dataset to meet nospace issue
27651         # quickly. then ZFS 0.7.2 can use reserved space if asked
27652         # properly (using netfree flag in osd_declare_destroy()
27653         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27654         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27655                 gawk '{print $3}')
27656         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27657         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27658         let "usedkb=usedkb-freekb"
27659         let "freekb=freekb/2"
27660         if let "freekb > 5000"; then
27661                 let "freekb=5000"
27662         fi
27663         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27664         trap cleanup_805 EXIT
27665         mkdir_on_mdt0 $DIR/$tdir
27666         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27667                 error "Can't set PFL layout"
27668         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27669         rm -rf $DIR/$tdir || error "not able to remove"
27670         do_facet $SINGLEMDS zfs set quota=$old $fsset
27671         trap 0
27672 }
27673 run_test 805 "ZFS can remove from full fs"
27674
27675 # Size-on-MDS test
27676 check_lsom_data()
27677 {
27678         local file=$1
27679         local expect=$(stat -c %s $file)
27680
27681         check_lsom_size $1 $expect
27682
27683         local blocks=$($LFS getsom -b $file)
27684         expect=$(stat -c %b $file)
27685         [[ $blocks == $expect ]] ||
27686                 error "$file expected blocks: $expect, got: $blocks"
27687 }
27688
27689 check_lsom_size()
27690 {
27691         local size
27692         local expect=$2
27693
27694         cancel_lru_locks mdc
27695
27696         size=$($LFS getsom -s $1)
27697         [[ $size == $expect ]] ||
27698                 error "$file expected size: $expect, got: $size"
27699 }
27700
27701 test_806() {
27702         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27703                 skip "Need MDS version at least 2.11.52"
27704
27705         local bs=1048576
27706
27707         touch $DIR/$tfile || error "touch $tfile failed"
27708
27709         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27710         save_lustre_params client "llite.*.xattr_cache" > $save
27711         lctl set_param llite.*.xattr_cache=0
27712         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27713
27714         # single-threaded write
27715         echo "Test SOM for single-threaded write"
27716         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27717                 error "write $tfile failed"
27718         check_lsom_size $DIR/$tfile $bs
27719
27720         local num=32
27721         local size=$(($num * $bs))
27722         local offset=0
27723         local i
27724
27725         echo "Test SOM for single client multi-threaded($num) write"
27726         $TRUNCATE $DIR/$tfile 0
27727         for ((i = 0; i < $num; i++)); do
27728                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27729                 local pids[$i]=$!
27730                 offset=$((offset + $bs))
27731         done
27732         for (( i=0; i < $num; i++ )); do
27733                 wait ${pids[$i]}
27734         done
27735         check_lsom_size $DIR/$tfile $size
27736
27737         $TRUNCATE $DIR/$tfile 0
27738         for ((i = 0; i < $num; i++)); do
27739                 offset=$((offset - $bs))
27740                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27741                 local pids[$i]=$!
27742         done
27743         for (( i=0; i < $num; i++ )); do
27744                 wait ${pids[$i]}
27745         done
27746         check_lsom_size $DIR/$tfile $size
27747
27748         # multi-client writes
27749         num=$(get_node_count ${CLIENTS//,/ })
27750         size=$(($num * $bs))
27751         offset=0
27752         i=0
27753
27754         echo "Test SOM for multi-client ($num) writes"
27755         $TRUNCATE $DIR/$tfile 0
27756         for client in ${CLIENTS//,/ }; do
27757                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27758                 local pids[$i]=$!
27759                 i=$((i + 1))
27760                 offset=$((offset + $bs))
27761         done
27762         for (( i=0; i < $num; i++ )); do
27763                 wait ${pids[$i]}
27764         done
27765         check_lsom_size $DIR/$tfile $offset
27766
27767         i=0
27768         $TRUNCATE $DIR/$tfile 0
27769         for client in ${CLIENTS//,/ }; do
27770                 offset=$((offset - $bs))
27771                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27772                 local pids[$i]=$!
27773                 i=$((i + 1))
27774         done
27775         for (( i=0; i < $num; i++ )); do
27776                 wait ${pids[$i]}
27777         done
27778         check_lsom_size $DIR/$tfile $size
27779
27780         # verify truncate
27781         echo "Test SOM for truncate"
27782         $TRUNCATE $DIR/$tfile 1048576
27783         check_lsom_size $DIR/$tfile 1048576
27784         $TRUNCATE $DIR/$tfile 1234
27785         check_lsom_size $DIR/$tfile 1234
27786
27787         # verify SOM blocks count
27788         echo "Verify SOM block count"
27789         $TRUNCATE $DIR/$tfile 0
27790         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27791                 error "failed to write file $tfile"
27792         check_lsom_data $DIR/$tfile
27793 }
27794 run_test 806 "Verify Lazy Size on MDS"
27795
27796 test_807() {
27797         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27798         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27799                 skip "Need MDS version at least 2.11.52"
27800
27801         # Registration step
27802         changelog_register || error "changelog_register failed"
27803         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27804         changelog_users $SINGLEMDS | grep -q $cl_user ||
27805                 error "User $cl_user not found in changelog_users"
27806
27807         rm -rf $DIR/$tdir || error "rm $tdir failed"
27808         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27809         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27810         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27811         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27812                 error "truncate $tdir/trunc failed"
27813
27814         local bs=1048576
27815         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27816                 error "write $tfile failed"
27817
27818         # multi-client wirtes
27819         local num=$(get_node_count ${CLIENTS//,/ })
27820         local offset=0
27821         local i=0
27822
27823         echo "Test SOM for multi-client ($num) writes"
27824         touch $DIR/$tfile || error "touch $tfile failed"
27825         $TRUNCATE $DIR/$tfile 0
27826         for client in ${CLIENTS//,/ }; do
27827                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27828                 local pids[$i]=$!
27829                 i=$((i + 1))
27830                 offset=$((offset + $bs))
27831         done
27832         for (( i=0; i < $num; i++ )); do
27833                 wait ${pids[$i]}
27834         done
27835
27836         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27837         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27838         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27839         check_lsom_data $DIR/$tdir/trunc
27840         check_lsom_data $DIR/$tdir/single_dd
27841         check_lsom_data $DIR/$tfile
27842
27843         rm -rf $DIR/$tdir
27844         # Deregistration step
27845         changelog_deregister || error "changelog_deregister failed"
27846 }
27847 run_test 807 "verify LSOM syncing tool"
27848
27849 check_som_nologged()
27850 {
27851         local lines=$($LFS changelog $FSNAME-MDT0000 |
27852                 grep 'x=trusted.som' | wc -l)
27853         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27854 }
27855
27856 test_808() {
27857         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27858                 skip "Need MDS version at least 2.11.55"
27859
27860         # Registration step
27861         changelog_register || error "changelog_register failed"
27862
27863         touch $DIR/$tfile || error "touch $tfile failed"
27864         check_som_nologged
27865
27866         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27867                 error "write $tfile failed"
27868         check_som_nologged
27869
27870         $TRUNCATE $DIR/$tfile 1234
27871         check_som_nologged
27872
27873         $TRUNCATE $DIR/$tfile 1048576
27874         check_som_nologged
27875
27876         # Deregistration step
27877         changelog_deregister || error "changelog_deregister failed"
27878 }
27879 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27880
27881 check_som_nodata()
27882 {
27883         $LFS getsom $1
27884         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27885 }
27886
27887 test_809() {
27888         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27889                 skip "Need MDS version at least 2.11.56"
27890
27891         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27892                 error "failed to create DoM-only file $DIR/$tfile"
27893         touch $DIR/$tfile || error "touch $tfile failed"
27894         check_som_nodata $DIR/$tfile
27895
27896         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27897                 error "write $tfile failed"
27898         check_som_nodata $DIR/$tfile
27899
27900         $TRUNCATE $DIR/$tfile 1234
27901         check_som_nodata $DIR/$tfile
27902
27903         $TRUNCATE $DIR/$tfile 4097
27904         check_som_nodata $DIR/$file
27905 }
27906 run_test 809 "Verify no SOM xattr store for DoM-only files"
27907
27908 test_810() {
27909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27910         $GSS && skip_env "could not run with gss"
27911         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27912                 skip "OST < 2.12.58 doesn't align checksum"
27913
27914         set_checksums 1
27915         stack_trap "set_checksums $ORIG_CSUM" EXIT
27916         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27917
27918         local csum
27919         local before
27920         local after
27921         for csum in $CKSUM_TYPES; do
27922                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27923                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27924                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27925                         eval set -- $i
27926                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27927                         before=$(md5sum $DIR/$tfile)
27928                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27929                         after=$(md5sum $DIR/$tfile)
27930                         [ "$before" == "$after" ] ||
27931                                 error "$csum: $before != $after bs=$1 seek=$2"
27932                 done
27933         done
27934 }
27935 run_test 810 "partial page writes on ZFS (LU-11663)"
27936
27937 test_812a() {
27938         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27939                 skip "OST < 2.12.51 doesn't support this fail_loc"
27940
27941         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27942         # ensure ost1 is connected
27943         stat $DIR/$tfile >/dev/null || error "can't stat"
27944         wait_osc_import_state client ost1 FULL
27945         # no locks, no reqs to let the connection idle
27946         cancel_lru_locks osc
27947
27948         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27949 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27950         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27951         wait_osc_import_state client ost1 CONNECTING
27952         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27953
27954         stat $DIR/$tfile >/dev/null || error "can't stat file"
27955 }
27956 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27957
27958 test_812b() { # LU-12378
27959         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27960                 skip "OST < 2.12.51 doesn't support this fail_loc"
27961
27962         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27963         # ensure ost1 is connected
27964         stat $DIR/$tfile >/dev/null || error "can't stat"
27965         wait_osc_import_state client ost1 FULL
27966         # no locks, no reqs to let the connection idle
27967         cancel_lru_locks osc
27968
27969         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27970 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27971         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27972         wait_osc_import_state client ost1 CONNECTING
27973         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27974
27975         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27976         wait_osc_import_state client ost1 IDLE
27977 }
27978 run_test 812b "do not drop no resend request for idle connect"
27979
27980 test_812c() {
27981         local old
27982
27983         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27984
27985         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27986         $LFS getstripe $DIR/$tfile
27987         $LCTL set_param osc.*.idle_timeout=10
27988         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27989         # ensure ost1 is connected
27990         stat $DIR/$tfile >/dev/null || error "can't stat"
27991         wait_osc_import_state client ost1 FULL
27992         # no locks, no reqs to let the connection idle
27993         cancel_lru_locks osc
27994
27995 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27996         $LCTL set_param fail_loc=0x80000533
27997         sleep 15
27998         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27999 }
28000 run_test 812c "idle import vs lock enqueue race"
28001
28002 test_813() {
28003         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28004         [ -z "$file_heat_sav" ] && skip "no file heat support"
28005
28006         local readsample
28007         local writesample
28008         local readbyte
28009         local writebyte
28010         local readsample1
28011         local writesample1
28012         local readbyte1
28013         local writebyte1
28014
28015         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28016         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28017
28018         $LCTL set_param -n llite.*.file_heat=1
28019         echo "Turn on file heat"
28020         echo "Period second: $period_second, Decay percentage: $decay_pct"
28021
28022         echo "QQQQ" > $DIR/$tfile
28023         echo "QQQQ" > $DIR/$tfile
28024         echo "QQQQ" > $DIR/$tfile
28025         cat $DIR/$tfile > /dev/null
28026         cat $DIR/$tfile > /dev/null
28027         cat $DIR/$tfile > /dev/null
28028         cat $DIR/$tfile > /dev/null
28029
28030         local out=$($LFS heat_get $DIR/$tfile)
28031
28032         $LFS heat_get $DIR/$tfile
28033         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28034         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28035         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28036         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28037
28038         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28039         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28040         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28041         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28042
28043         sleep $((period_second + 3))
28044         echo "Sleep $((period_second + 3)) seconds..."
28045         # The recursion formula to calculate the heat of the file f is as
28046         # follow:
28047         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28048         # Where Hi is the heat value in the period between time points i*I and
28049         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28050         # to the weight of Ci.
28051         out=$($LFS heat_get $DIR/$tfile)
28052         $LFS heat_get $DIR/$tfile
28053         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28054         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28055         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28056         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28057
28058         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28059                 error "read sample ($readsample) is wrong"
28060         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28061                 error "write sample ($writesample) is wrong"
28062         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28063                 error "read bytes ($readbyte) is wrong"
28064         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28065                 error "write bytes ($writebyte) is wrong"
28066
28067         echo "QQQQ" > $DIR/$tfile
28068         echo "QQQQ" > $DIR/$tfile
28069         echo "QQQQ" > $DIR/$tfile
28070         cat $DIR/$tfile > /dev/null
28071         cat $DIR/$tfile > /dev/null
28072         cat $DIR/$tfile > /dev/null
28073         cat $DIR/$tfile > /dev/null
28074
28075         sleep $((period_second + 3))
28076         echo "Sleep $((period_second + 3)) seconds..."
28077
28078         out=$($LFS heat_get $DIR/$tfile)
28079         $LFS heat_get $DIR/$tfile
28080         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28081         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28082         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28083         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28084
28085         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28086                 4 * $decay_pct) / 100") -eq 1 ] ||
28087                 error "read sample ($readsample1) is wrong"
28088         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28089                 3 * $decay_pct) / 100") -eq 1 ] ||
28090                 error "write sample ($writesample1) is wrong"
28091         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28092                 20 * $decay_pct) / 100") -eq 1 ] ||
28093                 error "read bytes ($readbyte1) is wrong"
28094         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28095                 15 * $decay_pct) / 100") -eq 1 ] ||
28096                 error "write bytes ($writebyte1) is wrong"
28097
28098         echo "Turn off file heat for the file $DIR/$tfile"
28099         $LFS heat_set -o $DIR/$tfile
28100
28101         echo "QQQQ" > $DIR/$tfile
28102         echo "QQQQ" > $DIR/$tfile
28103         echo "QQQQ" > $DIR/$tfile
28104         cat $DIR/$tfile > /dev/null
28105         cat $DIR/$tfile > /dev/null
28106         cat $DIR/$tfile > /dev/null
28107         cat $DIR/$tfile > /dev/null
28108
28109         out=$($LFS heat_get $DIR/$tfile)
28110         $LFS heat_get $DIR/$tfile
28111         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28112         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28113         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28114         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28115
28116         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28117         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28118         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28119         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28120
28121         echo "Trun on file heat for the file $DIR/$tfile"
28122         $LFS heat_set -O $DIR/$tfile
28123
28124         echo "QQQQ" > $DIR/$tfile
28125         echo "QQQQ" > $DIR/$tfile
28126         echo "QQQQ" > $DIR/$tfile
28127         cat $DIR/$tfile > /dev/null
28128         cat $DIR/$tfile > /dev/null
28129         cat $DIR/$tfile > /dev/null
28130         cat $DIR/$tfile > /dev/null
28131
28132         out=$($LFS heat_get $DIR/$tfile)
28133         $LFS heat_get $DIR/$tfile
28134         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28135         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28136         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28137         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28138
28139         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28140         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28141         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28142         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28143
28144         $LFS heat_set -c $DIR/$tfile
28145         $LCTL set_param -n llite.*.file_heat=0
28146         echo "Turn off file heat support for the Lustre filesystem"
28147
28148         echo "QQQQ" > $DIR/$tfile
28149         echo "QQQQ" > $DIR/$tfile
28150         echo "QQQQ" > $DIR/$tfile
28151         cat $DIR/$tfile > /dev/null
28152         cat $DIR/$tfile > /dev/null
28153         cat $DIR/$tfile > /dev/null
28154         cat $DIR/$tfile > /dev/null
28155
28156         out=$($LFS heat_get $DIR/$tfile)
28157         $LFS heat_get $DIR/$tfile
28158         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28159         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28160         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28161         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28162
28163         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28164         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28165         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28166         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28167
28168         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28169         rm -f $DIR/$tfile
28170 }
28171 run_test 813 "File heat verfication"
28172
28173 test_814()
28174 {
28175         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28176         echo -n y >> $DIR/$tfile
28177         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28178         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28179 }
28180 run_test 814 "sparse cp works as expected (LU-12361)"
28181
28182 test_815()
28183 {
28184         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28185         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28186 }
28187 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28188
28189 test_816() {
28190         local ost1_imp=$(get_osc_import_name client ost1)
28191         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28192                          cut -d'.' -f2)
28193
28194         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28195         # ensure ost1 is connected
28196
28197         stat $DIR/$tfile >/dev/null || error "can't stat"
28198         wait_osc_import_state client ost1 FULL
28199         # no locks, no reqs to let the connection idle
28200         cancel_lru_locks osc
28201         lru_resize_disable osc
28202         local before
28203         local now
28204         before=$($LCTL get_param -n \
28205                  ldlm.namespaces.$imp_name.lru_size)
28206
28207         wait_osc_import_state client ost1 IDLE
28208         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28209         now=$($LCTL get_param -n \
28210               ldlm.namespaces.$imp_name.lru_size)
28211         [ $before == $now ] || error "lru_size changed $before != $now"
28212 }
28213 run_test 816 "do not reset lru_resize on idle reconnect"
28214
28215 cleanup_817() {
28216         umount $tmpdir
28217         exportfs -u localhost:$DIR/nfsexp
28218         rm -rf $DIR/nfsexp
28219 }
28220
28221 test_817() {
28222         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28223
28224         mkdir -p $DIR/nfsexp
28225         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28226                 error "failed to export nfs"
28227
28228         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28229         stack_trap cleanup_817 EXIT
28230
28231         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28232                 error "failed to mount nfs to $tmpdir"
28233
28234         cp /bin/true $tmpdir
28235         $DIR/nfsexp/true || error "failed to execute 'true' command"
28236 }
28237 run_test 817 "nfsd won't cache write lock for exec file"
28238
28239 test_818() {
28240         test_mkdir -i0 -c1 $DIR/$tdir
28241         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28242         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28243         stop $SINGLEMDS
28244
28245         # restore osp-syn threads
28246         stack_trap "fail $SINGLEMDS"
28247
28248         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28249         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28250         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28251                 error "start $SINGLEMDS failed"
28252         rm -rf $DIR/$tdir
28253
28254         local testid=$(echo $TESTNAME | tr '_' ' ')
28255
28256         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28257                 grep "run LFSCK" || error "run LFSCK is not suggested"
28258 }
28259 run_test 818 "unlink with failed llog"
28260
28261 test_819a() {
28262         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28263         cancel_lru_locks osc
28264         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28265         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28266         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28267         rm -f $TDIR/$tfile
28268 }
28269 run_test 819a "too big niobuf in read"
28270
28271 test_819b() {
28272         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28273         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28274         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28275         cancel_lru_locks osc
28276         sleep 1
28277         rm -f $TDIR/$tfile
28278 }
28279 run_test 819b "too big niobuf in write"
28280
28281
28282 function test_820_start_ost() {
28283         sleep 5
28284
28285         for num in $(seq $OSTCOUNT); do
28286                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28287         done
28288 }
28289
28290 test_820() {
28291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28292
28293         mkdir $DIR/$tdir
28294         umount_client $MOUNT || error "umount failed"
28295         for num in $(seq $OSTCOUNT); do
28296                 stop ost$num
28297         done
28298
28299         # mount client with no active OSTs
28300         # so that the client can't initialize max LOV EA size
28301         # from OSC notifications
28302         mount_client $MOUNT || error "mount failed"
28303         # delay OST starting to keep this 0 max EA size for a while
28304         test_820_start_ost &
28305
28306         # create a directory on MDS2
28307         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28308                 error "Failed to create directory"
28309         # open intent should update default EA size
28310         # see mdc_update_max_ea_from_body()
28311         # notice this is the very first RPC to MDS2
28312         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28313         ret=$?
28314         echo $out
28315         # With SSK, this situation can lead to -EPERM being returned.
28316         # In that case, simply retry.
28317         if [ $ret -ne 0 ] && $SHARED_KEY; then
28318                 if echo "$out" | grep -q "not permitted"; then
28319                         cp /etc/services $DIR/$tdir/mds2
28320                         ret=$?
28321                 fi
28322         fi
28323         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28324 }
28325 run_test 820 "update max EA from open intent"
28326
28327 test_822() {
28328         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28329
28330         save_lustre_params mds1 \
28331                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28332         do_facet $SINGLEMDS "$LCTL set_param -n \
28333                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28334         do_facet $SINGLEMDS "$LCTL set_param -n \
28335                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28336
28337         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28338         local maxage=$(do_facet mds1 $LCTL get_param -n \
28339                        osp.$FSNAME-OST0000*MDT0000.maxage)
28340         sleep $((maxage + 1))
28341
28342         #define OBD_FAIL_NET_ERROR_RPC          0x532
28343         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28344
28345         stack_trap "restore_lustre_params < $p; rm $p"
28346
28347         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28348                       osp.$FSNAME-OST0000*MDT0000.create_count")
28349         for i in $(seq 1 $count); do
28350                 touch $DIR/$tfile.${i} || error "touch failed"
28351         done
28352 }
28353 run_test 822 "test precreate failure"
28354
28355 test_823() {
28356         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28357         local OST_MAX_PRECREATE=20000
28358
28359         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28360                 skip "Need MDS version at least 2.14.56"
28361
28362         save_lustre_params mds1 \
28363                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28364         do_facet $SINGLEMDS "$LCTL set_param -n \
28365                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28366         do_facet $SINGLEMDS "$LCTL set_param -n \
28367                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28368
28369         stack_trap "restore_lustre_params < $p; rm $p"
28370
28371         do_facet $SINGLEMDS "$LCTL set_param -n \
28372                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28373
28374         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28375                       osp.$FSNAME-OST0000*MDT0000.create_count")
28376         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28377                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28378         local expect_count=$(((($max/2)/256) * 256))
28379
28380         log "setting create_count to 100200:"
28381         log " -result- count: $count with max: $max, expecting: $expect_count"
28382
28383         [[ $count -eq expect_count ]] ||
28384                 error "Create count not set to max precreate."
28385 }
28386 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28387
28388 test_831() {
28389         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28390                 skip "Need MDS version 2.14.56"
28391
28392         local sync_changes=$(do_facet $SINGLEMDS \
28393                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28394
28395         [ "$sync_changes" -gt 100 ] &&
28396                 skip "Sync changes $sync_changes > 100 already"
28397
28398         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28399
28400         $LFS mkdir -i 0 $DIR/$tdir
28401         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28402
28403         save_lustre_params mds1 \
28404                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28405         save_lustre_params mds1 \
28406                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28407
28408         do_facet mds1 "$LCTL set_param -n \
28409                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28410                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28411         stack_trap "restore_lustre_params < $p" EXIT
28412
28413         createmany -o $DIR/$tdir/f- 1000
28414         unlinkmany $DIR/$tdir/f- 1000 &
28415         local UNLINK_PID=$!
28416
28417         while sleep 1; do
28418                 sync_changes=$(do_facet mds1 \
28419                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28420                 # the check in the code is racy, fail the test
28421                 # if the value above the limit by 10.
28422                 [ $sync_changes -gt 110 ] && {
28423                         kill -2 $UNLINK_PID
28424                         wait
28425                         error "osp changes throttling failed, $sync_changes>110"
28426                 }
28427                 kill -0 $UNLINK_PID 2> /dev/null || break
28428         done
28429         wait
28430 }
28431 run_test 831 "throttling unlink/setattr queuing on OSP"
28432
28433 #
28434 # tests that do cleanup/setup should be run at the end
28435 #
28436
28437 test_900() {
28438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28439         local ls
28440
28441         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28442         $LCTL set_param fail_loc=0x903
28443
28444         cancel_lru_locks MGC
28445
28446         FAIL_ON_ERROR=true cleanup
28447         FAIL_ON_ERROR=true setup
28448 }
28449 run_test 900 "umount should not race with any mgc requeue thread"
28450
28451 # LUS-6253/LU-11185
28452 test_901() {
28453         local old
28454         local count
28455         local oldc
28456         local newc
28457         local olds
28458         local news
28459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28460
28461         # some get_param have a bug to handle dot in param name
28462         cancel_lru_locks MGC
28463         old=$(mount -t lustre | wc -l)
28464         # 1 config+sptlrpc
28465         # 2 params
28466         # 3 nodemap
28467         # 4 IR
28468         old=$((old * 4))
28469         oldc=0
28470         count=0
28471         while [ $old -ne $oldc ]; do
28472                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28473                 sleep 1
28474                 ((count++))
28475                 if [ $count -ge $TIMEOUT ]; then
28476                         error "too large timeout"
28477                 fi
28478         done
28479         umount_client $MOUNT || error "umount failed"
28480         mount_client $MOUNT || error "mount failed"
28481         cancel_lru_locks MGC
28482         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28483
28484         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28485
28486         return 0
28487 }
28488 run_test 901 "don't leak a mgc lock on client umount"
28489
28490 # LU-13377
28491 test_902() {
28492         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28493                 skip "client does not have LU-13377 fix"
28494         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28495         $LCTL set_param fail_loc=0x1415
28496         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28497         cancel_lru_locks osc
28498         rm -f $DIR/$tfile
28499 }
28500 run_test 902 "test short write doesn't hang lustre"
28501
28502 # LU-14711
28503 test_903() {
28504         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28505         echo "blah" > $DIR/${tfile}-2
28506         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28507         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28508         $LCTL set_param fail_loc=0x417 fail_val=20
28509
28510         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28511         sleep 1 # To start the destroy
28512         wait_destroy_complete 150 || error "Destroy taking too long"
28513         cat $DIR/$tfile > /dev/null || error "Evicted"
28514 }
28515 run_test 903 "Test long page discard does not cause evictions"
28516
28517 test_904() {
28518         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28519         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28520                 grep -q project || skip "skip project quota not supported"
28521
28522         local testfile="$DIR/$tdir/$tfile"
28523         local xattr="trusted.projid"
28524         local projid
28525         local mdts=$(comma_list $(mdts_nodes))
28526         local saved=$(do_facet mds1 $LCTL get_param -n \
28527                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28528
28529         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28530         stack_trap "do_nodes $mdts $LCTL set_param \
28531                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28532
28533         mkdir -p $DIR/$tdir
28534         touch $testfile
28535         #hide projid xattr on server
28536         $LFS project -p 1 $testfile ||
28537                 error "set $testfile project id failed"
28538         getfattr -m - $testfile | grep $xattr &&
28539                 error "do not show trusted.projid when disabled on server"
28540         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28541         #should be hidden when projid is 0
28542         $LFS project -p 0 $testfile ||
28543                 error "set $testfile project id failed"
28544         getfattr -m - $testfile | grep $xattr &&
28545                 error "do not show trusted.projid with project ID 0"
28546
28547         #still can getxattr explicitly
28548         projid=$(getfattr -n $xattr $testfile |
28549                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28550         [ $projid == "0" ] ||
28551                 error "projid expected 0 not $projid"
28552
28553         #set the projid via setxattr
28554         setfattr -n $xattr -v "1000" $testfile ||
28555                 error "setattr failed with $?"
28556         projid=($($LFS project $testfile))
28557         [ ${projid[0]} == "1000" ] ||
28558                 error "projid expected 1000 not $projid"
28559
28560         #check the new projid via getxattr
28561         $LFS project -p 1001 $testfile ||
28562                 error "set $testfile project id failed"
28563         getfattr -m - $testfile | grep $xattr ||
28564                 error "should show trusted.projid when project ID != 0"
28565         projid=$(getfattr -n $xattr $testfile |
28566                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28567         [ $projid == "1001" ] ||
28568                 error "projid expected 1001 not $projid"
28569
28570         #try to set invalid projid
28571         setfattr -n $xattr -v "4294967295" $testfile &&
28572                 error "set invalid projid should fail"
28573
28574         #remove the xattr means setting projid to 0
28575         setfattr -x $xattr $testfile ||
28576                 error "setfattr failed with $?"
28577         projid=($($LFS project $testfile))
28578         [ ${projid[0]} == "0" ] ||
28579                 error "projid expected 0 not $projid"
28580
28581         #should be hidden when parent has inherit flag and same projid
28582         $LFS project -srp 1002 $DIR/$tdir ||
28583                 error "set $tdir project id failed"
28584         getfattr -m - $testfile | grep $xattr &&
28585                 error "do not show trusted.projid with inherit flag"
28586
28587         #still can getxattr explicitly
28588         projid=$(getfattr -n $xattr $testfile |
28589                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28590         [ $projid == "1002" ] ||
28591                 error "projid expected 1002 not $projid"
28592 }
28593 run_test 904 "virtual project ID xattr"
28594
28595 # LU-8582
28596 test_905() {
28597         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
28598                 skip "lustre < 2.8.54 does not support ladvise"
28599
28600         remote_ost_nodsh && skip "remote OST with nodsh"
28601         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
28602
28603         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
28604
28605         #define OBD_FAIL_OST_OPCODE 0x253
28606         # OST_LADVISE = 21
28607         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
28608         $LFS ladvise -a willread $DIR/$tfile &&
28609                 error "unexpected success of ladvise with fault injection"
28610         $LFS ladvise -a willread $DIR/$tfile |&
28611                 grep -q "Operation not supported"
28612         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
28613 }
28614 run_test 905 "bad or new opcode should not stuck client"
28615
28616 complete $SECONDS
28617 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28618 check_and_cleanup_lustre
28619 if [ "$I_MOUNTED" != "yes" ]; then
28620         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28621 fi
28622 exit_status