Whamcloud - gitweb
5422fb51c1b0fcdcdfc750dec7a28934c50eb02f
[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         test_mkdir $DIR/$tdir
2966
2967         # Set default striping on directory
2968         local setcount=4
2969         local stripe_opt
2970
2971         # if we run against a 2.12 server which lacks overstring support
2972         # then the connect_flag will not report overstriping, even if client
2973         # is 2.14+
2974         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2975                 stripe_opt="-C $setcount"
2976         elif (( $OSTCOUNT >= $setcount )); then
2977                 stripe_opt="-c $setcount"
2978         else
2979                 skip "server does not support overstriping"
2980         fi
2981         $LFS setstripe $stripe_opt $DIR/$tdir
2982
2983         echo 1 > $DIR/$tdir/${tfile}.1
2984         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2985         [ $count -eq $setcount ] ||
2986                 error "(1) stripe count $count, should be $setcount"
2987
2988         # Capture existing append_stripe_count setting for restore
2989         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2990         local mdts=$(comma_list $(mdts_nodes))
2991         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2992
2993         local appendcount=$orig_count
2994         echo 1 >> $DIR/$tdir/${tfile}.2_append
2995         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2996         [ $count -eq $appendcount ] ||
2997                 error "(2)stripe count $count, should be $appendcount for append"
2998
2999         # Disable O_APPEND striping, verify it works
3000         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3001
3002         # Should now get the default striping, which is 4
3003         setcount=4
3004         echo 1 >> $DIR/$tdir/${tfile}.3_append
3005         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3006         [ $count -eq $setcount ] ||
3007                 error "(3) stripe count $count, should be $setcount"
3008
3009         # Try changing the stripe count for append files
3010         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3011
3012         # Append striping is now 2 (directory default is still 4)
3013         appendcount=2
3014         echo 1 >> $DIR/$tdir/${tfile}.4_append
3015         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3016         [ $count -eq $appendcount ] ||
3017                 error "(4) stripe count $count, should be $appendcount for append"
3018
3019         # Test append stripe count of -1
3020         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3021         appendcount=$OSTCOUNT
3022         echo 1 >> $DIR/$tdir/${tfile}.5
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3024         [ $count -eq $appendcount ] ||
3025                 error "(5) stripe count $count, should be $appendcount for append"
3026
3027         # Set append striping back to default of 1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3029
3030         # Try a new default striping, PFL + DOM
3031         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3032
3033         # Create normal DOM file, DOM returns stripe count == 0
3034         setcount=0
3035         touch $DIR/$tdir/${tfile}.6
3036         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3037         [ $count -eq $setcount ] ||
3038                 error "(6) stripe count $count, should be $setcount"
3039
3040         # Show
3041         appendcount=1
3042         echo 1 >> $DIR/$tdir/${tfile}.7_append
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3044         [ $count -eq $appendcount ] ||
3045                 error "(7) stripe count $count, should be $appendcount for append"
3046
3047         # Clean up DOM layout
3048         $LFS setstripe -d $DIR/$tdir
3049
3050         save_layout_restore_at_exit $MOUNT
3051         # Now test that append striping works when layout is from root
3052         $LFS setstripe -c 2 $MOUNT
3053         # Make a special directory for this
3054         mkdir $DIR/${tdir}/${tdir}.2
3055
3056         # Verify for normal file
3057         setcount=2
3058         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3059         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3060         [ $count -eq $setcount ] ||
3061                 error "(8) stripe count $count, should be $setcount"
3062
3063         appendcount=1
3064         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3065         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3066         [ $count -eq $appendcount ] ||
3067                 error "(9) stripe count $count, should be $appendcount for append"
3068
3069         # Now test O_APPEND striping with pools
3070         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3071         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3072
3073         # Create the pool
3074         pool_add $TESTNAME || error "pool creation failed"
3075         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3076
3077         echo 1 >> $DIR/$tdir/${tfile}.10_append
3078
3079         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3080         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3081
3082         # Check that count is still correct
3083         appendcount=1
3084         echo 1 >> $DIR/$tdir/${tfile}.11_append
3085         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3086         [ $count -eq $appendcount ] ||
3087                 error "(11) stripe count $count, should be $appendcount for append"
3088
3089         # Disable O_APPEND stripe count, verify pool works separately
3090         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3091
3092         echo 1 >> $DIR/$tdir/${tfile}.12_append
3093
3094         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3095         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3096
3097         # Remove pool setting, verify it's not applied
3098         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3099
3100         echo 1 >> $DIR/$tdir/${tfile}.13_append
3101
3102         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3103         [ "$pool" = "" ] || error "(13) pool found: $pool"
3104 }
3105 run_test 27M "test O_APPEND striping"
3106
3107 test_27N() {
3108         combined_mgs_mds && skip "needs separate MGS/MDT"
3109
3110         pool_add $TESTNAME || error "pool_add failed"
3111         do_facet mgs "$LCTL pool_list $FSNAME" |
3112                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3113                 error "lctl pool_list on MGS failed"
3114 }
3115 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3116
3117 clean_foreign_symlink() {
3118         trap 0
3119         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3120         for i in $DIR/$tdir/* ; do
3121                 $LFS unlink_foreign $i || true
3122         done
3123 }
3124
3125 test_27O() {
3126         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3127                 skip "Need MDS version newer than 2.12.51"
3128
3129         test_mkdir $DIR/$tdir
3130         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3131         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3132
3133         trap clean_foreign_symlink EXIT
3134
3135         # enable foreign_symlink behaviour
3136         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3137
3138         # foreign symlink LOV format is a partial path by default
3139
3140         # create foreign file (lfs + API)
3141         $LFS setstripe --foreign=symlink --flags 0xda05 \
3142                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3143                 error "$DIR/$tdir/${tfile}: create failed"
3144
3145         $LFS getstripe -v $DIR/$tdir/${tfile} |
3146                 grep "lfm_magic:.*0x0BD70BD0" ||
3147                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3148         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3150         $LFS getstripe -v $DIR/$tdir/${tfile} |
3151                 grep "lfm_flags:.*0x0000DA05" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3153         $LFS getstripe $DIR/$tdir/${tfile} |
3154                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3155                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3156
3157         # modify striping should fail
3158         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3159                 error "$DIR/$tdir/$tfile: setstripe should fail"
3160
3161         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3162         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3163         cat /etc/passwd > $DIR/$tdir/$tfile &&
3164                 error "$DIR/$tdir/$tfile: write should fail"
3165
3166         # rename should succeed
3167         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3168                 error "$DIR/$tdir/$tfile: rename has failed"
3169
3170         #remove foreign_symlink file should fail
3171         rm $DIR/$tdir/${tfile}.new &&
3172                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3173
3174         #test fake symlink
3175         mkdir /tmp/${uuid1} ||
3176                 error "/tmp/${uuid1}: mkdir has failed"
3177         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3178                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3179         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3180         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3181                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3182         #read should succeed now
3183         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3184                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3185         #write should succeed now
3186         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3187                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3188         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3190         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3191                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3192
3193         #check that getstripe still works
3194         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3195                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3196
3197         # chmod should still succeed
3198         chmod 644 $DIR/$tdir/${tfile}.new ||
3199                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3200
3201         # chown should still succeed
3202         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3203                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3204
3205         # rename should still succeed
3206         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3207                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3208
3209         #remove foreign_symlink file should still fail
3210         rm $DIR/$tdir/${tfile} &&
3211                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3212
3213         #use special ioctl() to unlink foreign_symlink file
3214         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3215                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3216
3217 }
3218 run_test 27O "basic ops on foreign file of symlink type"
3219
3220 test_27P() {
3221         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3222                 skip "Need MDS version newer than 2.12.49"
3223
3224         test_mkdir $DIR/$tdir
3225         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3226         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3227
3228         trap clean_foreign_symlink EXIT
3229
3230         # enable foreign_symlink behaviour
3231         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3232
3233         # foreign symlink LMV format is a partial path by default
3234
3235         # create foreign dir (lfs + API)
3236         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3237                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3238                 error "$DIR/$tdir/${tdir}: create failed"
3239
3240         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3241
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3243                 grep "lfm_magic:.*0x0CD50CD0" ||
3244                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3245         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3248                 grep "lfm_flags:.*0x0000DA05" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3250         $LFS getdirstripe $DIR/$tdir/${tdir} |
3251                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3253
3254         # file create in dir should fail
3255         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3256         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3257
3258         # rename should succeed
3259         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3260                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3261
3262         #remove foreign_symlink dir should fail
3263         rmdir $DIR/$tdir/${tdir}.new &&
3264                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3265
3266         #test fake symlink
3267         mkdir -p /tmp/${uuid1}/${uuid2} ||
3268                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3269         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3270                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3271         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3272         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3273                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3274         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3275                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3276
3277         #check that getstripe fails now that foreign_symlink enabled
3278         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3279                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3280
3281         # file create in dir should work now
3282         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3283                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3284         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3285                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3286         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3287                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3288
3289         # chmod should still succeed
3290         chmod 755 $DIR/$tdir/${tdir}.new ||
3291                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3292
3293         # chown should still succeed
3294         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3295                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3296
3297         # rename should still succeed
3298         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3299                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3300
3301         #remove foreign_symlink dir should still fail
3302         rmdir $DIR/$tdir/${tdir} &&
3303                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3304
3305         #use special ioctl() to unlink foreign_symlink file
3306         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3307                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3308
3309         #created file should still exist
3310         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3311                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3312         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3313                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3314 }
3315 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3316
3317 test_27Q() {
3318         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3319         stack_trap "rm -f $TMP/$tfile*"
3320
3321         test_mkdir $DIR/$tdir-1
3322         test_mkdir $DIR/$tdir-2
3323
3324         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3325         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3326
3327         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3328         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3329
3330         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3331         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3332
3333         # Create some bad symlinks and ensure that we don't loop
3334         # forever or something. These should return ELOOP (40) and
3335         # ENOENT (2) but I don't want to test for that because there's
3336         # always some weirdo architecture that needs to ruin
3337         # everything by defining these error numbers differently.
3338
3339         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3340         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3341
3342         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3343         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3344
3345         return 0
3346 }
3347 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3348
3349 test_27R() {
3350         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3351                 skip "need MDS 2.14.55 or later"
3352         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3353
3354         local testdir="$DIR/$tdir"
3355         test_mkdir -p $testdir
3356         stack_trap "rm -rf $testdir"
3357         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3358
3359         local f1="$testdir/f1"
3360         touch $f1 || error "failed to touch $f1"
3361         local count=$($LFS getstripe -c $f1)
3362         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3363
3364         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3365         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3366
3367         local maxcount=$(($OSTCOUNT - 1))
3368         local mdts=$(comma_list $(mdts_nodes))
3369         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3370         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3371
3372         local f2="$testdir/f2"
3373         touch $f2 || error "failed to touch $f2"
3374         local count=$($LFS getstripe -c $f2)
3375         (( $count == $maxcount )) || error "wrong stripe count"
3376 }
3377 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3378
3379 test_27S() {
3380         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3381                 skip "Need MDS version at least 2.14.54"
3382         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3383                 skip "needs different host for mdt1 ost1"
3384
3385         local count=$(precreated_ost_obj_count 0 0)
3386
3387         echo "precreate count $count"
3388         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3389         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3390         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3391         do_facet mds1 $LCTL set_param fail_loc=0x2109
3392         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3393         do_facet ost1 $LCTL set_param fail_loc=0x252
3394         createmany -o $DIR/$tdir/f $count &
3395         pid=$!
3396         echo "precreate count $(precreated_ost_obj_count 0 0)"
3397         do_facet mds1 $LCTL set_param fail_loc=0
3398         do_facet ost1 $LCTL set_param fail_loc=0
3399         wait $pid || error "createmany failed"
3400         echo "precreate count $(precreated_ost_obj_count 0 0)"
3401 }
3402 run_test 27S "don't deactivate OSP on network issue"
3403
3404 test_27T() {
3405         [ $(facet_host client) == $(facet_host ost1) ] &&
3406                 skip "need ost1 and client on different nodes"
3407
3408 #define OBD_FAIL_OSC_NO_GRANT            0x411
3409         $LCTL set_param fail_loc=0x20000411 fail_val=1
3410 #define OBD_FAIL_OST_ENOSPC              0x215
3411         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3412         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3413         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3414                 error "multiop failed"
3415 }
3416 run_test 27T "no eio on close on partial write due to enosp"
3417
3418 # createtest also checks that device nodes are created and
3419 # then visible correctly (#2091)
3420 test_28() { # bug 2091
3421         test_mkdir $DIR/d28
3422         $CREATETEST $DIR/d28/ct || error "createtest failed"
3423 }
3424 run_test 28 "create/mknod/mkdir with bad file types ============"
3425
3426 test_29() {
3427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3428
3429         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3430                 disable_opencache
3431                 stack_trap "restore_opencache"
3432         }
3433
3434         sync; sleep 1; sync # flush out any dirty pages from previous tests
3435         cancel_lru_locks
3436         test_mkdir $DIR/d29
3437         touch $DIR/d29/foo
3438         log 'first d29'
3439         ls -l $DIR/d29
3440
3441         declare -i LOCKCOUNTORIG=0
3442         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3443                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3444         done
3445         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3446
3447         declare -i LOCKUNUSEDCOUNTORIG=0
3448         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3449                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3450         done
3451
3452         log 'second d29'
3453         ls -l $DIR/d29
3454         log 'done'
3455
3456         declare -i LOCKCOUNTCURRENT=0
3457         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3458                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3459         done
3460
3461         declare -i LOCKUNUSEDCOUNTCURRENT=0
3462         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3463                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3464         done
3465
3466         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3467                 $LCTL set_param -n ldlm.dump_namespaces ""
3468                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3469                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3470                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3471                 return 2
3472         fi
3473         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3474                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3475                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3476                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3477                 return 3
3478         fi
3479 }
3480 run_test 29 "IT_GETATTR regression  ============================"
3481
3482 test_30a() { # was test_30
3483         cp $(which ls) $DIR || cp /bin/ls $DIR
3484         $DIR/ls / || error "Can't execute binary from lustre"
3485         rm $DIR/ls
3486 }
3487 run_test 30a "execute binary from Lustre (execve) =============="
3488
3489 test_30b() {
3490         cp `which ls` $DIR || cp /bin/ls $DIR
3491         chmod go+rx $DIR/ls
3492         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3493         rm $DIR/ls
3494 }
3495 run_test 30b "execute binary from Lustre as non-root ==========="
3496
3497 test_30c() { # b=22376
3498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3499
3500         cp $(which ls) $DIR || cp /bin/ls $DIR
3501         chmod a-rw $DIR/ls
3502         cancel_lru_locks mdc
3503         cancel_lru_locks osc
3504         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3505         rm -f $DIR/ls
3506 }
3507 run_test 30c "execute binary from Lustre without read perms ===="
3508
3509 test_30d() {
3510         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3511
3512         for i in {1..10}; do
3513                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3514                 local PID=$!
3515                 sleep 1
3516                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3517                 wait $PID || error "executing dd from Lustre failed"
3518                 rm -f $DIR/$tfile
3519         done
3520
3521         rm -f $DIR/dd
3522 }
3523 run_test 30d "execute binary from Lustre while clear locks"
3524
3525 test_31a() {
3526         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3527         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3528 }
3529 run_test 31a "open-unlink file =================================="
3530
3531 test_31b() {
3532         touch $DIR/f31 || error "touch $DIR/f31 failed"
3533         ln $DIR/f31 $DIR/f31b || error "ln failed"
3534         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3535         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3536 }
3537 run_test 31b "unlink file with multiple links while open ======="
3538
3539 test_31c() {
3540         touch $DIR/f31 || error "touch $DIR/f31 failed"
3541         ln $DIR/f31 $DIR/f31c || error "ln failed"
3542         multiop_bg_pause $DIR/f31 O_uc ||
3543                 error "multiop_bg_pause for $DIR/f31 failed"
3544         MULTIPID=$!
3545         $MULTIOP $DIR/f31c Ouc
3546         kill -USR1 $MULTIPID
3547         wait $MULTIPID
3548 }
3549 run_test 31c "open-unlink file with multiple links ============="
3550
3551 test_31d() {
3552         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3553         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3554 }
3555 run_test 31d "remove of open directory ========================="
3556
3557 test_31e() { # bug 2904
3558         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3559 }
3560 run_test 31e "remove of open non-empty directory ==============="
3561
3562 test_31f() { # bug 4554
3563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3564
3565         set -vx
3566         test_mkdir $DIR/d31f
3567         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3568         cp /etc/hosts $DIR/d31f
3569         ls -l $DIR/d31f
3570         $LFS getstripe $DIR/d31f/hosts
3571         multiop_bg_pause $DIR/d31f D_c || return 1
3572         MULTIPID=$!
3573
3574         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3575         test_mkdir $DIR/d31f
3576         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3577         cp /etc/hosts $DIR/d31f
3578         ls -l $DIR/d31f
3579         $LFS getstripe $DIR/d31f/hosts
3580         multiop_bg_pause $DIR/d31f D_c || return 1
3581         MULTIPID2=$!
3582
3583         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3584         wait $MULTIPID || error "first opendir $MULTIPID failed"
3585
3586         sleep 6
3587
3588         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3589         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3590         set +vx
3591 }
3592 run_test 31f "remove of open directory with open-unlink file ==="
3593
3594 test_31g() {
3595         echo "-- cross directory link --"
3596         test_mkdir -c1 $DIR/${tdir}ga
3597         test_mkdir -c1 $DIR/${tdir}gb
3598         touch $DIR/${tdir}ga/f
3599         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3600         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3601         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3602         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3603         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3604 }
3605 run_test 31g "cross directory link==============="
3606
3607 test_31h() {
3608         echo "-- cross directory link --"
3609         test_mkdir -c1 $DIR/${tdir}
3610         test_mkdir -c1 $DIR/${tdir}/dir
3611         touch $DIR/${tdir}/f
3612         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3613         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3614         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3615         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3616         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3617 }
3618 run_test 31h "cross directory link under child==============="
3619
3620 test_31i() {
3621         echo "-- cross directory link --"
3622         test_mkdir -c1 $DIR/$tdir
3623         test_mkdir -c1 $DIR/$tdir/dir
3624         touch $DIR/$tdir/dir/f
3625         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3626         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3627         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3628         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3629         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3630 }
3631 run_test 31i "cross directory link under parent==============="
3632
3633 test_31j() {
3634         test_mkdir -c1 -p $DIR/$tdir
3635         test_mkdir -c1 -p $DIR/$tdir/dir1
3636         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3637         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3638         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3639         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3640         return 0
3641 }
3642 run_test 31j "link for directory==============="
3643
3644 test_31k() {
3645         test_mkdir -c1 -p $DIR/$tdir
3646         touch $DIR/$tdir/s
3647         touch $DIR/$tdir/exist
3648         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3649         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3650         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3651         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3652         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3653         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3654         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3655         return 0
3656 }
3657 run_test 31k "link to file: the same, non-existing, dir==============="
3658
3659 test_31m() {
3660         mkdir $DIR/d31m
3661         touch $DIR/d31m/s
3662         mkdir $DIR/d31m2
3663         touch $DIR/d31m2/exist
3664         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3665         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3666         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3667         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3668         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3669         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3670         return 0
3671 }
3672 run_test 31m "link to file: the same, non-existing, dir==============="
3673
3674 test_31n() {
3675         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3676         nlink=$(stat --format=%h $DIR/$tfile)
3677         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3678         local fd=$(free_fd)
3679         local cmd="exec $fd<$DIR/$tfile"
3680         eval $cmd
3681         cmd="exec $fd<&-"
3682         trap "eval $cmd" EXIT
3683         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3684         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3685         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3686         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3687         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3688         eval $cmd
3689 }
3690 run_test 31n "check link count of unlinked file"
3691
3692 link_one() {
3693         local tempfile=$(mktemp $1_XXXXXX)
3694         mlink $tempfile $1 2> /dev/null &&
3695                 echo "$BASHPID: link $tempfile to $1 succeeded"
3696         munlink $tempfile
3697 }
3698
3699 test_31o() { # LU-2901
3700         test_mkdir $DIR/$tdir
3701         for LOOP in $(seq 100); do
3702                 rm -f $DIR/$tdir/$tfile*
3703                 for THREAD in $(seq 8); do
3704                         link_one $DIR/$tdir/$tfile.$LOOP &
3705                 done
3706                 wait
3707                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3708                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3709                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3710                         break || true
3711         done
3712 }
3713 run_test 31o "duplicate hard links with same filename"
3714
3715 test_31p() {
3716         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3717
3718         test_mkdir $DIR/$tdir
3719         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3720         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3721
3722         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3723                 error "open unlink test1 failed"
3724         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3725                 error "open unlink test2 failed"
3726
3727         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3728                 error "test1 still exists"
3729         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3730                 error "test2 still exists"
3731 }
3732 run_test 31p "remove of open striped directory"
3733
3734 test_31q() {
3735         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3736
3737         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3738         index=$($LFS getdirstripe -i $DIR/$tdir)
3739         [ $index -eq 3 ] || error "first stripe index $index != 3"
3740         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3741         [ $index -eq 1 ] || error "second stripe index $index != 1"
3742
3743         # when "-c <stripe_count>" is set, the number of MDTs specified after
3744         # "-i" should equal to the stripe count
3745         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3746 }
3747 run_test 31q "create striped directory on specific MDTs"
3748
3749 #LU-14949
3750 test_31r() {
3751         touch $DIR/$tfile.target
3752         touch $DIR/$tfile.source
3753
3754         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3755         $LCTL set_param fail_loc=0x1419 fail_val=3
3756         cat $DIR/$tfile.target &
3757         CATPID=$!
3758
3759         # Guarantee open is waiting before we get here
3760         sleep 1
3761         mv $DIR/$tfile.source $DIR/$tfile.target
3762
3763         wait $CATPID
3764         RC=$?
3765         if [[ $RC -ne 0 ]]; then
3766                 error "open with cat failed, rc=$RC"
3767         fi
3768 }
3769 run_test 31r "open-rename(replace) race"
3770
3771 cleanup_test32_mount() {
3772         local rc=0
3773         trap 0
3774         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3775         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3776         losetup -d $loopdev || true
3777         rm -rf $DIR/$tdir
3778         return $rc
3779 }
3780
3781 test_32a() {
3782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3783
3784         echo "== more mountpoints and symlinks ================="
3785         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3786         trap cleanup_test32_mount EXIT
3787         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3788         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3789                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3790         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3791                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3792         cleanup_test32_mount
3793 }
3794 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3795
3796 test_32b() {
3797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3798
3799         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3800         trap cleanup_test32_mount EXIT
3801         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3802         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3803                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3804         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3805                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3806         cleanup_test32_mount
3807 }
3808 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3809
3810 test_32c() {
3811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3812
3813         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3814         trap cleanup_test32_mount EXIT
3815         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3816         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3817                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3818         test_mkdir -p $DIR/$tdir/d2/test_dir
3819         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3820                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3821         cleanup_test32_mount
3822 }
3823 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3824
3825 test_32d() {
3826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3827
3828         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3829         trap cleanup_test32_mount EXIT
3830         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3831         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3832                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3833         test_mkdir -p $DIR/$tdir/d2/test_dir
3834         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3835                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3836         cleanup_test32_mount
3837 }
3838 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3839
3840 test_32e() {
3841         rm -fr $DIR/$tdir
3842         test_mkdir -p $DIR/$tdir/tmp
3843         local tmp_dir=$DIR/$tdir/tmp
3844         ln -s $DIR/$tdir $tmp_dir/symlink11
3845         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3846         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3847         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3848 }
3849 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3850
3851 test_32f() {
3852         rm -fr $DIR/$tdir
3853         test_mkdir -p $DIR/$tdir/tmp
3854         local tmp_dir=$DIR/$tdir/tmp
3855         ln -s $DIR/$tdir $tmp_dir/symlink11
3856         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3857         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3858         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3859 }
3860 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3861
3862 test_32g() {
3863         local tmp_dir=$DIR/$tdir/tmp
3864         test_mkdir -p $tmp_dir
3865         test_mkdir $DIR/${tdir}2
3866         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3867         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3868         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3869         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3870         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3871         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3872 }
3873 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3874
3875 test_32h() {
3876         rm -fr $DIR/$tdir $DIR/${tdir}2
3877         tmp_dir=$DIR/$tdir/tmp
3878         test_mkdir -p $tmp_dir
3879         test_mkdir $DIR/${tdir}2
3880         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3881         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3882         ls $tmp_dir/symlink12 || error "listing symlink12"
3883         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3884 }
3885 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3886
3887 test_32i() {
3888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3889
3890         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3891         trap cleanup_test32_mount EXIT
3892         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3893         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3894                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3895         touch $DIR/$tdir/test_file
3896         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3897                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3898         cleanup_test32_mount
3899 }
3900 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3901
3902 test_32j() {
3903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3904
3905         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3906         trap cleanup_test32_mount EXIT
3907         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3908         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3909                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3910         touch $DIR/$tdir/test_file
3911         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3912                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3913         cleanup_test32_mount
3914 }
3915 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3916
3917 test_32k() {
3918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3919
3920         rm -fr $DIR/$tdir
3921         trap cleanup_test32_mount EXIT
3922         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3923         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3924                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3925         test_mkdir -p $DIR/$tdir/d2
3926         touch $DIR/$tdir/d2/test_file || error "touch failed"
3927         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3928                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3929         cleanup_test32_mount
3930 }
3931 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3932
3933 test_32l() {
3934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3935
3936         rm -fr $DIR/$tdir
3937         trap cleanup_test32_mount EXIT
3938         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3939         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3940                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3941         test_mkdir -p $DIR/$tdir/d2
3942         touch $DIR/$tdir/d2/test_file || error "touch failed"
3943         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3944                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3945         cleanup_test32_mount
3946 }
3947 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3948
3949 test_32m() {
3950         rm -fr $DIR/d32m
3951         test_mkdir -p $DIR/d32m/tmp
3952         TMP_DIR=$DIR/d32m/tmp
3953         ln -s $DIR $TMP_DIR/symlink11
3954         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3955         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3956                 error "symlink11 not a link"
3957         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3958                 error "symlink01 not a link"
3959 }
3960 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3961
3962 test_32n() {
3963         rm -fr $DIR/d32n
3964         test_mkdir -p $DIR/d32n/tmp
3965         TMP_DIR=$DIR/d32n/tmp
3966         ln -s $DIR $TMP_DIR/symlink11
3967         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3968         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3969         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3970 }
3971 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3972
3973 test_32o() {
3974         touch $DIR/$tfile
3975         test_mkdir -p $DIR/d32o/tmp
3976         TMP_DIR=$DIR/d32o/tmp
3977         ln -s $DIR/$tfile $TMP_DIR/symlink12
3978         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3979         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3980                 error "symlink12 not a link"
3981         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3982         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3983                 error "$DIR/d32o/tmp/symlink12 not file type"
3984         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3985                 error "$DIR/d32o/symlink02 not file type"
3986 }
3987 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3988
3989 test_32p() {
3990         log 32p_1
3991         rm -fr $DIR/d32p
3992         log 32p_2
3993         rm -f $DIR/$tfile
3994         log 32p_3
3995         touch $DIR/$tfile
3996         log 32p_4
3997         test_mkdir -p $DIR/d32p/tmp
3998         log 32p_5
3999         TMP_DIR=$DIR/d32p/tmp
4000         log 32p_6
4001         ln -s $DIR/$tfile $TMP_DIR/symlink12
4002         log 32p_7
4003         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4004         log 32p_8
4005         cat $DIR/d32p/tmp/symlink12 ||
4006                 error "Can't open $DIR/d32p/tmp/symlink12"
4007         log 32p_9
4008         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4009         log 32p_10
4010 }
4011 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4012
4013 test_32q() {
4014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4015
4016         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4017         trap cleanup_test32_mount EXIT
4018         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4019         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4020         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4021                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4022         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4023         cleanup_test32_mount
4024 }
4025 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4026
4027 test_32r() {
4028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4029
4030         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4031         trap cleanup_test32_mount EXIT
4032         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4033         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4034         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4035                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4036         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4037         cleanup_test32_mount
4038 }
4039 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4040
4041 test_33aa() {
4042         rm -f $DIR/$tfile
4043         touch $DIR/$tfile
4044         chmod 444 $DIR/$tfile
4045         chown $RUNAS_ID $DIR/$tfile
4046         log 33_1
4047         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4048         log 33_2
4049 }
4050 run_test 33aa "write file with mode 444 (should return error)"
4051
4052 test_33a() {
4053         rm -fr $DIR/$tdir
4054         test_mkdir $DIR/$tdir
4055         chown $RUNAS_ID $DIR/$tdir
4056         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4057                 error "$RUNAS create $tdir/$tfile failed"
4058         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4059                 error "open RDWR" || true
4060 }
4061 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4062
4063 test_33b() {
4064         rm -fr $DIR/$tdir
4065         test_mkdir $DIR/$tdir
4066         chown $RUNAS_ID $DIR/$tdir
4067         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4068 }
4069 run_test 33b "test open file with malformed flags (No panic)"
4070
4071 test_33c() {
4072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4073         remote_ost_nodsh && skip "remote OST with nodsh"
4074
4075         local ostnum
4076         local ostname
4077         local write_bytes
4078         local all_zeros
4079
4080         all_zeros=true
4081         test_mkdir $DIR/$tdir
4082         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4083
4084         sync
4085         for ostnum in $(seq $OSTCOUNT); do
4086                 # test-framework's OST numbering is one-based, while Lustre's
4087                 # is zero-based
4088                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4089                 # check if at least some write_bytes stats are counted
4090                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4091                               obdfilter.$ostname.stats |
4092                               awk '/^write_bytes/ {print $7}' )
4093                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4094                 if (( ${write_bytes:-0} > 0 )); then
4095                         all_zeros=false
4096                         break
4097                 fi
4098         done
4099
4100         $all_zeros || return 0
4101
4102         # Write four bytes
4103         echo foo > $DIR/$tdir/bar
4104         # Really write them
4105         sync
4106
4107         # Total up write_bytes after writing.  We'd better find non-zeros.
4108         for ostnum in $(seq $OSTCOUNT); do
4109                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4110                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4111                               obdfilter/$ostname/stats |
4112                               awk '/^write_bytes/ {print $7}' )
4113                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4114                 if (( ${write_bytes:-0} > 0 )); then
4115                         all_zeros=false
4116                         break
4117                 fi
4118         done
4119
4120         if $all_zeros; then
4121                 for ostnum in $(seq $OSTCOUNT); do
4122                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4123                         echo "Check write_bytes is in obdfilter.*.stats:"
4124                         do_facet ost$ostnum lctl get_param -n \
4125                                 obdfilter.$ostname.stats
4126                 done
4127                 error "OST not keeping write_bytes stats (b=22312)"
4128         fi
4129 }
4130 run_test 33c "test write_bytes stats"
4131
4132 test_33d() {
4133         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4135
4136         local MDTIDX=1
4137         local remote_dir=$DIR/$tdir/remote_dir
4138
4139         test_mkdir $DIR/$tdir
4140         $LFS mkdir -i $MDTIDX $remote_dir ||
4141                 error "create remote directory failed"
4142
4143         touch $remote_dir/$tfile
4144         chmod 444 $remote_dir/$tfile
4145         chown $RUNAS_ID $remote_dir/$tfile
4146
4147         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4148
4149         chown $RUNAS_ID $remote_dir
4150         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4151                                         error "create" || true
4152         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4153                                     error "open RDWR" || true
4154         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4155 }
4156 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4157
4158 test_33e() {
4159         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4160
4161         mkdir $DIR/$tdir
4162
4163         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4164         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4165         mkdir $DIR/$tdir/local_dir
4166
4167         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4168         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4169         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4170
4171         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4172                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4173
4174         rmdir $DIR/$tdir/* || error "rmdir failed"
4175
4176         umask 777
4177         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4178         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4179         mkdir $DIR/$tdir/local_dir
4180
4181         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4182         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4183         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4184
4185         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4186                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4187
4188         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4189
4190         umask 000
4191         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4192         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4193         mkdir $DIR/$tdir/local_dir
4194
4195         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4196         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4197         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4198
4199         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4200                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4201 }
4202 run_test 33e "mkdir and striped directory should have same mode"
4203
4204 cleanup_33f() {
4205         trap 0
4206         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4207 }
4208
4209 test_33f() {
4210         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4211         remote_mds_nodsh && skip "remote MDS with nodsh"
4212
4213         mkdir $DIR/$tdir
4214         chmod go+rwx $DIR/$tdir
4215         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4216         trap cleanup_33f EXIT
4217
4218         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4219                 error "cannot create striped directory"
4220
4221         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4222                 error "cannot create files in striped directory"
4223
4224         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4225                 error "cannot remove files in striped directory"
4226
4227         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4228                 error "cannot remove striped directory"
4229
4230         cleanup_33f
4231 }
4232 run_test 33f "nonroot user can create, access, and remove a striped directory"
4233
4234 test_33g() {
4235         mkdir -p $DIR/$tdir/dir2
4236
4237         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4238         echo $err
4239         [[ $err =~ "exists" ]] || error "Not exists error"
4240 }
4241 run_test 33g "nonroot user create already existing root created file"
4242
4243 sub_33h() {
4244         local hash_type=$1
4245         local count=250
4246
4247         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4248                 error "lfs mkdir -H $hash_type $tdir failed"
4249         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4250
4251         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4252         local index2
4253         local fname
4254
4255         for fname in $DIR/$tdir/$tfile.bak \
4256                      $DIR/$tdir/$tfile.SAV \
4257                      $DIR/$tdir/$tfile.orig \
4258                      $DIR/$tdir/$tfile~; do
4259                 touch $fname || error "touch $fname failed"
4260                 index2=$($LFS getstripe -m $fname)
4261                 (( $index == $index2 )) ||
4262                         error "$fname MDT index mismatch $index != $index2"
4263         done
4264
4265         local failed=0
4266         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4267         local pattern
4268
4269         for pattern in ${patterns[*]}; do
4270                 echo "pattern $pattern"
4271                 fname=$DIR/$tdir/$pattern
4272                 for (( i = 0; i < $count; i++ )); do
4273                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4274                                 error "mktemp $DIR/$tdir/$pattern failed"
4275                         index2=$($LFS getstripe -m $fname)
4276                         (( $index == $index2 )) && continue
4277
4278                         failed=$((failed + 1))
4279                         echo "$fname MDT index mismatch $index != $index2"
4280                 done
4281         done
4282
4283         echo "$failed/$count MDT index mismatches, expect ~2-4"
4284         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4285
4286         local same=0
4287         local expect
4288
4289         # verify that "crush" is still broken with all files on same MDT,
4290         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4291         [[ "$hash_type" == "crush" ]] && expect=$count ||
4292                 expect=$((count / MDSCOUNT))
4293
4294         # crush2 doesn't put all-numeric suffixes on the same MDT,
4295         # filename like $tfile.12345678 should *not* be considered temp
4296         for pattern in ${patterns[*]}; do
4297                 local base=${pattern%%X*}
4298                 local suff=${pattern#$base}
4299
4300                 echo "pattern $pattern"
4301                 for (( i = 0; i < $count; i++ )); do
4302                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4303                         touch $fname || error "touch $fname failed"
4304                         index2=$($LFS getstripe -m $fname)
4305                         (( $index != $index2 )) && continue
4306
4307                         same=$((same + 1))
4308                 done
4309         done
4310
4311         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4312         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4313            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4314                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4315         same=0
4316
4317         # crush2 doesn't put suffixes with special characters on the same MDT
4318         # filename like $tfile.txt.1234 should *not* be considered temp
4319         for pattern in ${patterns[*]}; do
4320                 local base=${pattern%%X*}
4321                 local suff=${pattern#$base}
4322
4323                 pattern=$base...${suff/XXX}
4324                 echo "pattern=$pattern"
4325                 for (( i = 0; i < $count; i++ )); do
4326                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4327                                 error "touch $fname failed"
4328                         index2=$($LFS getstripe -m $fname)
4329                         (( $index != $index2 )) && continue
4330
4331                         same=$((same + 1))
4332                 done
4333         done
4334
4335         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4336         (( same / ${#patterns[*]} < expect * 5 / 4 &&
4337            same / ${#patterns[*]} > expect * 4 / 5 )) ||
4338                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4339 }
4340
4341 test_33h() {
4342         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4343         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4344                 skip "Need MDS version at least 2.13.50"
4345
4346         sub_33h crush
4347 }
4348 run_test 33h "temp file is located on the same MDT as target (crush)"
4349
4350 test_33hh() {
4351         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4352         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4353         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4354                 skip "Need MDS version at least 2.15.0 for crush2"
4355
4356         sub_33h crush2
4357 }
4358 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4359
4360 test_33i()
4361 {
4362         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4363
4364         local FNAME=$(str_repeat 'f' 250)
4365
4366         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4367         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4368
4369         local count
4370         local total
4371
4372         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4373
4374         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4375
4376         lctl --device %$MDC deactivate
4377         stack_trap "lctl --device %$MDC activate"
4378         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4379         total=$(\ls -l $DIR/$tdir | wc -l)
4380         # "ls -l" will list total in the first line
4381         total=$((total - 1))
4382         (( total + count == 1000 )) ||
4383                 error "ls list $total files, $count files on MDT1"
4384 }
4385 run_test 33i "striped directory can be accessed when one MDT is down"
4386
4387 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4388 test_34a() {
4389         rm -f $DIR/f34
4390         $MCREATE $DIR/f34 || error "mcreate failed"
4391         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4392                 error "getstripe failed"
4393         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4394         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4395                 error "getstripe failed"
4396         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4397                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4398 }
4399 run_test 34a "truncate file that has not been opened ==========="
4400
4401 test_34b() {
4402         [ ! -f $DIR/f34 ] && test_34a
4403         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4404                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4405         $OPENFILE -f O_RDONLY $DIR/f34
4406         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4407                 error "getstripe failed"
4408         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4409                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4410 }
4411 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4412
4413 test_34c() {
4414         [ ! -f $DIR/f34 ] && test_34a
4415         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4416                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4417         $OPENFILE -f O_RDWR $DIR/f34
4418         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4419                 error "$LFS getstripe failed"
4420         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4421                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4422 }
4423 run_test 34c "O_RDWR opening file-with-size works =============="
4424
4425 test_34d() {
4426         [ ! -f $DIR/f34 ] && test_34a
4427         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4428                 error "dd failed"
4429         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4430                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4431         rm $DIR/f34
4432 }
4433 run_test 34d "write to sparse file ============================="
4434
4435 test_34e() {
4436         rm -f $DIR/f34e
4437         $MCREATE $DIR/f34e || error "mcreate failed"
4438         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4439         $CHECKSTAT -s 1000 $DIR/f34e ||
4440                 error "Size of $DIR/f34e not equal to 1000 bytes"
4441         $OPENFILE -f O_RDWR $DIR/f34e
4442         $CHECKSTAT -s 1000 $DIR/f34e ||
4443                 error "Size of $DIR/f34e not equal to 1000 bytes"
4444 }
4445 run_test 34e "create objects, some with size and some without =="
4446
4447 test_34f() { # bug 6242, 6243
4448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4449
4450         SIZE34F=48000
4451         rm -f $DIR/f34f
4452         $MCREATE $DIR/f34f || error "mcreate failed"
4453         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4454         dd if=$DIR/f34f of=$TMP/f34f
4455         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4456         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4457         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4458         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4459         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4460 }
4461 run_test 34f "read from a file with no objects until EOF ======="
4462
4463 test_34g() {
4464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4465
4466         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4467                 error "dd failed"
4468         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4469         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4470                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4471         cancel_lru_locks osc
4472         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4473                 error "wrong size after lock cancel"
4474
4475         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4476         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4477                 error "expanding truncate failed"
4478         cancel_lru_locks osc
4479         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4480                 error "wrong expanded size after lock cancel"
4481 }
4482 run_test 34g "truncate long file ==============================="
4483
4484 test_34h() {
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         local gid=10
4488         local sz=1000
4489
4490         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4491         sync # Flush the cache so that multiop below does not block on cache
4492              # flush when getting the group lock
4493         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4494         MULTIPID=$!
4495
4496         # Since just timed wait is not good enough, let's do a sync write
4497         # that way we are sure enough time for a roundtrip + processing
4498         # passed + 2 seconds of extra margin.
4499         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4500         rm $DIR/${tfile}-1
4501         sleep 2
4502
4503         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4504                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4505                 kill -9 $MULTIPID
4506         fi
4507         wait $MULTIPID
4508         local nsz=`stat -c %s $DIR/$tfile`
4509         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4510 }
4511 run_test 34h "ftruncate file under grouplock should not block"
4512
4513 test_35a() {
4514         cp /bin/sh $DIR/f35a
4515         chmod 444 $DIR/f35a
4516         chown $RUNAS_ID $DIR/f35a
4517         $RUNAS $DIR/f35a && error || true
4518         rm $DIR/f35a
4519 }
4520 run_test 35a "exec file with mode 444 (should return and not leak)"
4521
4522 test_36a() {
4523         rm -f $DIR/f36
4524         utime $DIR/f36 || error "utime failed for MDS"
4525 }
4526 run_test 36a "MDS utime check (mknod, utime)"
4527
4528 test_36b() {
4529         echo "" > $DIR/f36
4530         utime $DIR/f36 || error "utime failed for OST"
4531 }
4532 run_test 36b "OST utime check (open, utime)"
4533
4534 test_36c() {
4535         rm -f $DIR/d36/f36
4536         test_mkdir $DIR/d36
4537         chown $RUNAS_ID $DIR/d36
4538         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4539 }
4540 run_test 36c "non-root MDS utime check (mknod, utime)"
4541
4542 test_36d() {
4543         [ ! -d $DIR/d36 ] && test_36c
4544         echo "" > $DIR/d36/f36
4545         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4546 }
4547 run_test 36d "non-root OST utime check (open, utime)"
4548
4549 test_36e() {
4550         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4551
4552         test_mkdir $DIR/$tdir
4553         touch $DIR/$tdir/$tfile
4554         $RUNAS utime $DIR/$tdir/$tfile &&
4555                 error "utime worked, expected failure" || true
4556 }
4557 run_test 36e "utime on non-owned file (should return error)"
4558
4559 subr_36fh() {
4560         local fl="$1"
4561         local LANG_SAVE=$LANG
4562         local LC_LANG_SAVE=$LC_LANG
4563         export LANG=C LC_LANG=C # for date language
4564
4565         DATESTR="Dec 20  2000"
4566         test_mkdir $DIR/$tdir
4567         lctl set_param fail_loc=$fl
4568         date; date +%s
4569         cp /etc/hosts $DIR/$tdir/$tfile
4570         sync & # write RPC generated with "current" inode timestamp, but delayed
4571         sleep 1
4572         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4573         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4574         cancel_lru_locks $OSC
4575         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4576         date; date +%s
4577         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4578                 echo "BEFORE: $LS_BEFORE" && \
4579                 echo "AFTER : $LS_AFTER" && \
4580                 echo "WANT  : $DATESTR" && \
4581                 error "$DIR/$tdir/$tfile timestamps changed" || true
4582
4583         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4584 }
4585
4586 test_36f() {
4587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4588
4589         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4590         subr_36fh "0x80000214"
4591 }
4592 run_test 36f "utime on file racing with OST BRW write =========="
4593
4594 test_36g() {
4595         remote_ost_nodsh && skip "remote OST with nodsh"
4596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4597         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4598                 skip "Need MDS version at least 2.12.51"
4599
4600         local fmd_max_age
4601         local fmd
4602         local facet="ost1"
4603         local tgt="obdfilter"
4604
4605         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4606
4607         test_mkdir $DIR/$tdir
4608         fmd_max_age=$(do_facet $facet \
4609                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4610                 head -n 1")
4611
4612         echo "FMD max age: ${fmd_max_age}s"
4613         touch $DIR/$tdir/$tfile
4614         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4615                 gawk '{cnt=cnt+$1}  END{print cnt}')
4616         echo "FMD before: $fmd"
4617         [[ $fmd == 0 ]] &&
4618                 error "FMD wasn't create by touch"
4619         sleep $((fmd_max_age + 12))
4620         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4621                 gawk '{cnt=cnt+$1}  END{print cnt}')
4622         echo "FMD after: $fmd"
4623         [[ $fmd == 0 ]] ||
4624                 error "FMD wasn't expired by ping"
4625 }
4626 run_test 36g "FMD cache expiry ====================="
4627
4628 test_36h() {
4629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4630
4631         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4632         subr_36fh "0x80000227"
4633 }
4634 run_test 36h "utime on file racing with OST BRW write =========="
4635
4636 test_36i() {
4637         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4638
4639         test_mkdir $DIR/$tdir
4640         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4641
4642         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4643         local new_mtime=$((mtime + 200))
4644
4645         #change Modify time of striped dir
4646         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4647                         error "change mtime failed"
4648
4649         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4650
4651         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4652 }
4653 run_test 36i "change mtime on striped directory"
4654
4655 # test_37 - duplicate with tests 32q 32r
4656
4657 test_38() {
4658         local file=$DIR/$tfile
4659         touch $file
4660         openfile -f O_DIRECTORY $file
4661         local RC=$?
4662         local ENOTDIR=20
4663         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4664         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4665 }
4666 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4667
4668 test_39a() { # was test_39
4669         touch $DIR/$tfile
4670         touch $DIR/${tfile}2
4671 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4672 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4673 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4674         sleep 2
4675         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4676         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4677                 echo "mtime"
4678                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4679                 echo "atime"
4680                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4681                 echo "ctime"
4682                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4683                 error "O_TRUNC didn't change timestamps"
4684         fi
4685 }
4686 run_test 39a "mtime changed on create"
4687
4688 test_39b() {
4689         test_mkdir -c1 $DIR/$tdir
4690         cp -p /etc/passwd $DIR/$tdir/fopen
4691         cp -p /etc/passwd $DIR/$tdir/flink
4692         cp -p /etc/passwd $DIR/$tdir/funlink
4693         cp -p /etc/passwd $DIR/$tdir/frename
4694         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4695
4696         sleep 1
4697         echo "aaaaaa" >> $DIR/$tdir/fopen
4698         echo "aaaaaa" >> $DIR/$tdir/flink
4699         echo "aaaaaa" >> $DIR/$tdir/funlink
4700         echo "aaaaaa" >> $DIR/$tdir/frename
4701
4702         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4703         local link_new=`stat -c %Y $DIR/$tdir/flink`
4704         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4705         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4706
4707         cat $DIR/$tdir/fopen > /dev/null
4708         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4709         rm -f $DIR/$tdir/funlink2
4710         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4711
4712         for (( i=0; i < 2; i++ )) ; do
4713                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4714                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4715                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4716                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4717
4718                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4719                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4720                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4721                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4722
4723                 cancel_lru_locks $OSC
4724                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4725         done
4726 }
4727 run_test 39b "mtime change on open, link, unlink, rename  ======"
4728
4729 # this should be set to past
4730 TEST_39_MTIME=`date -d "1 year ago" +%s`
4731
4732 # bug 11063
4733 test_39c() {
4734         touch $DIR1/$tfile
4735         sleep 2
4736         local mtime0=`stat -c %Y $DIR1/$tfile`
4737
4738         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4739         local mtime1=`stat -c %Y $DIR1/$tfile`
4740         [ "$mtime1" = $TEST_39_MTIME ] || \
4741                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4742
4743         local d1=`date +%s`
4744         echo hello >> $DIR1/$tfile
4745         local d2=`date +%s`
4746         local mtime2=`stat -c %Y $DIR1/$tfile`
4747         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4748                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4749
4750         mv $DIR1/$tfile $DIR1/$tfile-1
4751
4752         for (( i=0; i < 2; i++ )) ; do
4753                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4754                 [ "$mtime2" = "$mtime3" ] || \
4755                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4756
4757                 cancel_lru_locks $OSC
4758                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4759         done
4760 }
4761 run_test 39c "mtime change on rename ==========================="
4762
4763 # bug 21114
4764 test_39d() {
4765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4766
4767         touch $DIR1/$tfile
4768         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4769
4770         for (( i=0; i < 2; i++ )) ; do
4771                 local mtime=`stat -c %Y $DIR1/$tfile`
4772                 [ $mtime = $TEST_39_MTIME ] || \
4773                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4774
4775                 cancel_lru_locks $OSC
4776                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4777         done
4778 }
4779 run_test 39d "create, utime, stat =============================="
4780
4781 # bug 21114
4782 test_39e() {
4783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4784
4785         touch $DIR1/$tfile
4786         local mtime1=`stat -c %Y $DIR1/$tfile`
4787
4788         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4789
4790         for (( i=0; i < 2; i++ )) ; do
4791                 local mtime2=`stat -c %Y $DIR1/$tfile`
4792                 [ $mtime2 = $TEST_39_MTIME ] || \
4793                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4794
4795                 cancel_lru_locks $OSC
4796                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4797         done
4798 }
4799 run_test 39e "create, stat, utime, stat ========================"
4800
4801 # bug 21114
4802 test_39f() {
4803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4804
4805         touch $DIR1/$tfile
4806         mtime1=`stat -c %Y $DIR1/$tfile`
4807
4808         sleep 2
4809         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4810
4811         for (( i=0; i < 2; i++ )) ; do
4812                 local mtime2=`stat -c %Y $DIR1/$tfile`
4813                 [ $mtime2 = $TEST_39_MTIME ] || \
4814                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4815
4816                 cancel_lru_locks $OSC
4817                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4818         done
4819 }
4820 run_test 39f "create, stat, sleep, utime, stat ================="
4821
4822 # bug 11063
4823 test_39g() {
4824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4825
4826         echo hello >> $DIR1/$tfile
4827         local mtime1=`stat -c %Y $DIR1/$tfile`
4828
4829         sleep 2
4830         chmod o+r $DIR1/$tfile
4831
4832         for (( i=0; i < 2; i++ )) ; do
4833                 local mtime2=`stat -c %Y $DIR1/$tfile`
4834                 [ "$mtime1" = "$mtime2" ] || \
4835                         error "lost mtime: $mtime2, should be $mtime1"
4836
4837                 cancel_lru_locks $OSC
4838                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4839         done
4840 }
4841 run_test 39g "write, chmod, stat ==============================="
4842
4843 # bug 11063
4844 test_39h() {
4845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4846
4847         touch $DIR1/$tfile
4848         sleep 1
4849
4850         local d1=`date`
4851         echo hello >> $DIR1/$tfile
4852         local mtime1=`stat -c %Y $DIR1/$tfile`
4853
4854         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4855         local d2=`date`
4856         if [ "$d1" != "$d2" ]; then
4857                 echo "write and touch not within one second"
4858         else
4859                 for (( i=0; i < 2; i++ )) ; do
4860                         local mtime2=`stat -c %Y $DIR1/$tfile`
4861                         [ "$mtime2" = $TEST_39_MTIME ] || \
4862                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4863
4864                         cancel_lru_locks $OSC
4865                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4866                 done
4867         fi
4868 }
4869 run_test 39h "write, utime within one second, stat ============="
4870
4871 test_39i() {
4872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4873
4874         touch $DIR1/$tfile
4875         sleep 1
4876
4877         echo hello >> $DIR1/$tfile
4878         local mtime1=`stat -c %Y $DIR1/$tfile`
4879
4880         mv $DIR1/$tfile $DIR1/$tfile-1
4881
4882         for (( i=0; i < 2; i++ )) ; do
4883                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4884
4885                 [ "$mtime1" = "$mtime2" ] || \
4886                         error "lost mtime: $mtime2, should be $mtime1"
4887
4888                 cancel_lru_locks $OSC
4889                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4890         done
4891 }
4892 run_test 39i "write, rename, stat =============================="
4893
4894 test_39j() {
4895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4896
4897         start_full_debug_logging
4898         touch $DIR1/$tfile
4899         sleep 1
4900
4901         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4902         lctl set_param fail_loc=0x80000412
4903         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4904                 error "multiop failed"
4905         local multipid=$!
4906         local mtime1=`stat -c %Y $DIR1/$tfile`
4907
4908         mv $DIR1/$tfile $DIR1/$tfile-1
4909
4910         kill -USR1 $multipid
4911         wait $multipid || error "multiop close failed"
4912
4913         for (( i=0; i < 2; i++ )) ; do
4914                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4915                 [ "$mtime1" = "$mtime2" ] ||
4916                         error "mtime is lost on close: $mtime2, " \
4917                               "should be $mtime1"
4918
4919                 cancel_lru_locks
4920                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4921         done
4922         lctl set_param fail_loc=0
4923         stop_full_debug_logging
4924 }
4925 run_test 39j "write, rename, close, stat ======================="
4926
4927 test_39k() {
4928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4929
4930         touch $DIR1/$tfile
4931         sleep 1
4932
4933         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4934         local multipid=$!
4935         local mtime1=`stat -c %Y $DIR1/$tfile`
4936
4937         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4938
4939         kill -USR1 $multipid
4940         wait $multipid || error "multiop close failed"
4941
4942         for (( i=0; i < 2; i++ )) ; do
4943                 local mtime2=`stat -c %Y $DIR1/$tfile`
4944
4945                 [ "$mtime2" = $TEST_39_MTIME ] || \
4946                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4947
4948                 cancel_lru_locks
4949                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4950         done
4951 }
4952 run_test 39k "write, utime, close, stat ========================"
4953
4954 # this should be set to future
4955 TEST_39_ATIME=`date -d "1 year" +%s`
4956
4957 test_39l() {
4958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4959         remote_mds_nodsh && skip "remote MDS with nodsh"
4960
4961         local atime_diff=$(do_facet $SINGLEMDS \
4962                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4963         rm -rf $DIR/$tdir
4964         mkdir_on_mdt0 $DIR/$tdir
4965
4966         # test setting directory atime to future
4967         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4968         local atime=$(stat -c %X $DIR/$tdir)
4969         [ "$atime" = $TEST_39_ATIME ] ||
4970                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4971
4972         # test setting directory atime from future to now
4973         local now=$(date +%s)
4974         touch -a -d @$now $DIR/$tdir
4975
4976         atime=$(stat -c %X $DIR/$tdir)
4977         [ "$atime" -eq "$now"  ] ||
4978                 error "atime is not updated from future: $atime, $now"
4979
4980         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4981         sleep 3
4982
4983         # test setting directory atime when now > dir atime + atime_diff
4984         local d1=$(date +%s)
4985         ls $DIR/$tdir
4986         local d2=$(date +%s)
4987         cancel_lru_locks mdc
4988         atime=$(stat -c %X $DIR/$tdir)
4989         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4990                 error "atime is not updated  : $atime, should be $d2"
4991
4992         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4993         sleep 3
4994
4995         # test not setting directory atime when now < dir atime + atime_diff
4996         ls $DIR/$tdir
4997         cancel_lru_locks mdc
4998         atime=$(stat -c %X $DIR/$tdir)
4999         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5000                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5001
5002         do_facet $SINGLEMDS \
5003                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5004 }
5005 run_test 39l "directory atime update ==========================="
5006
5007 test_39m() {
5008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5009
5010         touch $DIR1/$tfile
5011         sleep 2
5012         local far_past_mtime=$(date -d "May 29 1953" +%s)
5013         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5014
5015         touch -m -d @$far_past_mtime $DIR1/$tfile
5016         touch -a -d @$far_past_atime $DIR1/$tfile
5017
5018         for (( i=0; i < 2; i++ )) ; do
5019                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5020                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5021                         error "atime or mtime set incorrectly"
5022
5023                 cancel_lru_locks $OSC
5024                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5025         done
5026 }
5027 run_test 39m "test atime and mtime before 1970"
5028
5029 test_39n() { # LU-3832
5030         remote_mds_nodsh && skip "remote MDS with nodsh"
5031
5032         local atime_diff=$(do_facet $SINGLEMDS \
5033                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5034         local atime0
5035         local atime1
5036         local atime2
5037
5038         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5039
5040         rm -rf $DIR/$tfile
5041         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5042         atime0=$(stat -c %X $DIR/$tfile)
5043
5044         sleep 5
5045         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5046         atime1=$(stat -c %X $DIR/$tfile)
5047
5048         sleep 5
5049         cancel_lru_locks mdc
5050         cancel_lru_locks osc
5051         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5052         atime2=$(stat -c %X $DIR/$tfile)
5053
5054         do_facet $SINGLEMDS \
5055                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5056
5057         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5058         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5059 }
5060 run_test 39n "check that O_NOATIME is honored"
5061
5062 test_39o() {
5063         TESTDIR=$DIR/$tdir/$tfile
5064         [ -e $TESTDIR ] && rm -rf $TESTDIR
5065         mkdir -p $TESTDIR
5066         cd $TESTDIR
5067         links1=2
5068         ls
5069         mkdir a b
5070         ls
5071         links2=$(stat -c %h .)
5072         [ $(($links1 + 2)) != $links2 ] &&
5073                 error "wrong links count $(($links1 + 2)) != $links2"
5074         rmdir b
5075         links3=$(stat -c %h .)
5076         [ $(($links1 + 1)) != $links3 ] &&
5077                 error "wrong links count $links1 != $links3"
5078         return 0
5079 }
5080 run_test 39o "directory cached attributes updated after create"
5081
5082 test_39p() {
5083         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5084
5085         local MDTIDX=1
5086         TESTDIR=$DIR/$tdir/$tdir
5087         [ -e $TESTDIR ] && rm -rf $TESTDIR
5088         test_mkdir -p $TESTDIR
5089         cd $TESTDIR
5090         links1=2
5091         ls
5092         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5093         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5094         ls
5095         links2=$(stat -c %h .)
5096         [ $(($links1 + 2)) != $links2 ] &&
5097                 error "wrong links count $(($links1 + 2)) != $links2"
5098         rmdir remote_dir2
5099         links3=$(stat -c %h .)
5100         [ $(($links1 + 1)) != $links3 ] &&
5101                 error "wrong links count $links1 != $links3"
5102         return 0
5103 }
5104 run_test 39p "remote directory cached attributes updated after create ========"
5105
5106 test_39r() {
5107         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5108                 skip "no atime update on old OST"
5109         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5110                 skip_env "ldiskfs only test"
5111         fi
5112
5113         local saved_adiff
5114         saved_adiff=$(do_facet ost1 \
5115                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5116         stack_trap "do_facet ost1 \
5117                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5118
5119         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5120
5121         $LFS setstripe -i 0 $DIR/$tfile
5122         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5123                 error "can't write initial file"
5124         cancel_lru_locks osc
5125
5126         # exceed atime_diff and access file
5127         sleep 10
5128         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5129                 error "can't udpate atime"
5130
5131         local atime_cli=$(stat -c %X $DIR/$tfile)
5132         echo "client atime: $atime_cli"
5133         # allow atime update to be written to device
5134         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5135         sleep 5
5136
5137         local ostdev=$(ostdevname 1)
5138         local fid=($(lfs getstripe -y $DIR/$tfile |
5139                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5140         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5141         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5142
5143         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5144         local atime_ost=$(do_facet ost1 "$cmd" |&
5145                           awk -F'[: ]' '/atime:/ { print $4 }')
5146         (( atime_cli == atime_ost )) ||
5147                 error "atime on client $atime_cli != ost $atime_ost"
5148 }
5149 run_test 39r "lazy atime update on OST"
5150
5151 test_39q() { # LU-8041
5152         local testdir=$DIR/$tdir
5153         mkdir -p $testdir
5154         multiop_bg_pause $testdir D_c || error "multiop failed"
5155         local multipid=$!
5156         cancel_lru_locks mdc
5157         kill -USR1 $multipid
5158         local atime=$(stat -c %X $testdir)
5159         [ "$atime" -ne 0 ] || error "atime is zero"
5160 }
5161 run_test 39q "close won't zero out atime"
5162
5163 test_40() {
5164         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5165         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5166                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5167         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5168                 error "$tfile is not 4096 bytes in size"
5169 }
5170 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5171
5172 test_41() {
5173         # bug 1553
5174         small_write $DIR/f41 18
5175 }
5176 run_test 41 "test small file write + fstat ====================="
5177
5178 count_ost_writes() {
5179         lctl get_param -n ${OSC}.*.stats |
5180                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5181                         END { printf("%0.0f", writes) }'
5182 }
5183
5184 # decent default
5185 WRITEBACK_SAVE=500
5186 DIRTY_RATIO_SAVE=40
5187 MAX_DIRTY_RATIO=50
5188 BG_DIRTY_RATIO_SAVE=10
5189 MAX_BG_DIRTY_RATIO=25
5190
5191 start_writeback() {
5192         trap 0
5193         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5194         # dirty_ratio, dirty_background_ratio
5195         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5196                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5197                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5198                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5199         else
5200                 # if file not here, we are a 2.4 kernel
5201                 kill -CONT `pidof kupdated`
5202         fi
5203 }
5204
5205 stop_writeback() {
5206         # setup the trap first, so someone cannot exit the test at the
5207         # exact wrong time and mess up a machine
5208         trap start_writeback EXIT
5209         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5210         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5211                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5212                 sysctl -w vm.dirty_writeback_centisecs=0
5213                 sysctl -w vm.dirty_writeback_centisecs=0
5214                 # save and increase /proc/sys/vm/dirty_ratio
5215                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5216                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5217                 # save and increase /proc/sys/vm/dirty_background_ratio
5218                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5219                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5220         else
5221                 # if file not here, we are a 2.4 kernel
5222                 kill -STOP `pidof kupdated`
5223         fi
5224 }
5225
5226 # ensure that all stripes have some grant before we test client-side cache
5227 setup_test42() {
5228         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5229                 dd if=/dev/zero of=$i bs=4k count=1
5230                 rm $i
5231         done
5232 }
5233
5234 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5235 # file truncation, and file removal.
5236 test_42a() {
5237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5238
5239         setup_test42
5240         cancel_lru_locks $OSC
5241         stop_writeback
5242         sync; sleep 1; sync # just to be safe
5243         BEFOREWRITES=`count_ost_writes`
5244         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5245         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5246         AFTERWRITES=`count_ost_writes`
5247         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5248                 error "$BEFOREWRITES < $AFTERWRITES"
5249         start_writeback
5250 }
5251 run_test 42a "ensure that we don't flush on close"
5252
5253 test_42b() {
5254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5255
5256         setup_test42
5257         cancel_lru_locks $OSC
5258         stop_writeback
5259         sync
5260         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5261         BEFOREWRITES=$(count_ost_writes)
5262         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5263         AFTERWRITES=$(count_ost_writes)
5264         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5265                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5266         fi
5267         BEFOREWRITES=$(count_ost_writes)
5268         sync || error "sync: $?"
5269         AFTERWRITES=$(count_ost_writes)
5270         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5271                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5272         fi
5273         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5274         start_writeback
5275         return 0
5276 }
5277 run_test 42b "test destroy of file with cached dirty data ======"
5278
5279 # if these tests just want to test the effect of truncation,
5280 # they have to be very careful.  consider:
5281 # - the first open gets a {0,EOF}PR lock
5282 # - the first write conflicts and gets a {0, count-1}PW
5283 # - the rest of the writes are under {count,EOF}PW
5284 # - the open for truncate tries to match a {0,EOF}PR
5285 #   for the filesize and cancels the PWs.
5286 # any number of fixes (don't get {0,EOF} on open, match
5287 # composite locks, do smarter file size management) fix
5288 # this, but for now we want these tests to verify that
5289 # the cancellation with truncate intent works, so we
5290 # start the file with a full-file pw lock to match against
5291 # until the truncate.
5292 trunc_test() {
5293         test=$1
5294         file=$DIR/$test
5295         offset=$2
5296         cancel_lru_locks $OSC
5297         stop_writeback
5298         # prime the file with 0,EOF PW to match
5299         touch $file
5300         $TRUNCATE $file 0
5301         sync; sync
5302         # now the real test..
5303         dd if=/dev/zero of=$file bs=1024 count=100
5304         BEFOREWRITES=`count_ost_writes`
5305         $TRUNCATE $file $offset
5306         cancel_lru_locks $OSC
5307         AFTERWRITES=`count_ost_writes`
5308         start_writeback
5309 }
5310
5311 test_42c() {
5312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5313
5314         trunc_test 42c 1024
5315         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5316                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5317         rm $file
5318 }
5319 run_test 42c "test partial truncate of file with cached dirty data"
5320
5321 test_42d() {
5322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5323
5324         trunc_test 42d 0
5325         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5326                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5327         rm $file
5328 }
5329 run_test 42d "test complete truncate of file with cached dirty data"
5330
5331 test_42e() { # bug22074
5332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5333
5334         local TDIR=$DIR/${tdir}e
5335         local pages=16 # hardcoded 16 pages, don't change it.
5336         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5337         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5338         local max_dirty_mb
5339         local warmup_files
5340
5341         test_mkdir $DIR/${tdir}e
5342         $LFS setstripe -c 1 $TDIR
5343         createmany -o $TDIR/f $files
5344
5345         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5346
5347         # we assume that with $OSTCOUNT files, at least one of them will
5348         # be allocated on OST0.
5349         warmup_files=$((OSTCOUNT * max_dirty_mb))
5350         createmany -o $TDIR/w $warmup_files
5351
5352         # write a large amount of data into one file and sync, to get good
5353         # avail_grant number from OST.
5354         for ((i=0; i<$warmup_files; i++)); do
5355                 idx=$($LFS getstripe -i $TDIR/w$i)
5356                 [ $idx -ne 0 ] && continue
5357                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5358                 break
5359         done
5360         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5361         sync
5362         $LCTL get_param $proc_osc0/cur_dirty_bytes
5363         $LCTL get_param $proc_osc0/cur_grant_bytes
5364
5365         # create as much dirty pages as we can while not to trigger the actual
5366         # RPCs directly. but depends on the env, VFS may trigger flush during this
5367         # period, hopefully we are good.
5368         for ((i=0; i<$warmup_files; i++)); do
5369                 idx=$($LFS getstripe -i $TDIR/w$i)
5370                 [ $idx -ne 0 ] && continue
5371                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5372         done
5373         $LCTL get_param $proc_osc0/cur_dirty_bytes
5374         $LCTL get_param $proc_osc0/cur_grant_bytes
5375
5376         # perform the real test
5377         $LCTL set_param $proc_osc0/rpc_stats 0
5378         for ((;i<$files; i++)); do
5379                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5380                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5381         done
5382         sync
5383         $LCTL get_param $proc_osc0/rpc_stats
5384
5385         local percent=0
5386         local have_ppr=false
5387         $LCTL get_param $proc_osc0/rpc_stats |
5388                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5389                         # skip lines until we are at the RPC histogram data
5390                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5391                         $have_ppr || continue
5392
5393                         # we only want the percent stat for < 16 pages
5394                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5395
5396                         percent=$((percent + WPCT))
5397                         if [[ $percent -gt 15 ]]; then
5398                                 error "less than 16-pages write RPCs" \
5399                                       "$percent% > 15%"
5400                                 break
5401                         fi
5402                 done
5403         rm -rf $TDIR
5404 }
5405 run_test 42e "verify sub-RPC writes are not done synchronously"
5406
5407 test_43A() { # was test_43
5408         test_mkdir $DIR/$tdir
5409         cp -p /bin/ls $DIR/$tdir/$tfile
5410         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5411         pid=$!
5412         # give multiop a chance to open
5413         sleep 1
5414
5415         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5416         kill -USR1 $pid
5417         # Wait for multiop to exit
5418         wait $pid
5419 }
5420 run_test 43A "execution of file opened for write should return -ETXTBSY"
5421
5422 test_43a() {
5423         test_mkdir $DIR/$tdir
5424         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5425         $DIR/$tdir/sleep 60 &
5426         SLEEP_PID=$!
5427         # Make sure exec of $tdir/sleep wins race with truncate
5428         sleep 1
5429         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5430         kill $SLEEP_PID
5431 }
5432 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5433
5434 test_43b() {
5435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5436
5437         test_mkdir $DIR/$tdir
5438         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5439         $DIR/$tdir/sleep 60 &
5440         SLEEP_PID=$!
5441         # Make sure exec of $tdir/sleep wins race with truncate
5442         sleep 1
5443         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5444         kill $SLEEP_PID
5445 }
5446 run_test 43b "truncate of file being executed should return -ETXTBSY"
5447
5448 test_43c() {
5449         local testdir="$DIR/$tdir"
5450         test_mkdir $testdir
5451         cp $SHELL $testdir/
5452         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5453                 ( cd $testdir && md5sum -c )
5454 }
5455 run_test 43c "md5sum of copy into lustre"
5456
5457 test_44A() { # was test_44
5458         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5459
5460         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5461         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5462 }
5463 run_test 44A "zero length read from a sparse stripe"
5464
5465 test_44a() {
5466         local nstripe=$($LFS getstripe -c -d $DIR)
5467         [ -z "$nstripe" ] && skip "can't get stripe info"
5468         [[ $nstripe -gt $OSTCOUNT ]] &&
5469                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5470
5471         local stride=$($LFS getstripe -S -d $DIR)
5472         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5473                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5474         fi
5475
5476         OFFSETS="0 $((stride/2)) $((stride-1))"
5477         for offset in $OFFSETS; do
5478                 for i in $(seq 0 $((nstripe-1))); do
5479                         local GLOBALOFFSETS=""
5480                         # size in Bytes
5481                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5482                         local myfn=$DIR/d44a-$size
5483                         echo "--------writing $myfn at $size"
5484                         ll_sparseness_write $myfn $size ||
5485                                 error "ll_sparseness_write"
5486                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5487                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5488                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5489
5490                         for j in $(seq 0 $((nstripe-1))); do
5491                                 # size in Bytes
5492                                 size=$((((j + $nstripe )*$stride + $offset)))
5493                                 ll_sparseness_write $myfn $size ||
5494                                         error "ll_sparseness_write"
5495                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5496                         done
5497                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5498                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5499                         rm -f $myfn
5500                 done
5501         done
5502 }
5503 run_test 44a "test sparse pwrite ==============================="
5504
5505 dirty_osc_total() {
5506         tot=0
5507         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5508                 tot=$(($tot + $d))
5509         done
5510         echo $tot
5511 }
5512 do_dirty_record() {
5513         before=`dirty_osc_total`
5514         echo executing "\"$*\""
5515         eval $*
5516         after=`dirty_osc_total`
5517         echo before $before, after $after
5518 }
5519 test_45() {
5520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5521
5522         f="$DIR/f45"
5523         # Obtain grants from OST if it supports it
5524         echo blah > ${f}_grant
5525         stop_writeback
5526         sync
5527         do_dirty_record "echo blah > $f"
5528         [[ $before -eq $after ]] && error "write wasn't cached"
5529         do_dirty_record "> $f"
5530         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5531         do_dirty_record "echo blah > $f"
5532         [[ $before -eq $after ]] && error "write wasn't cached"
5533         do_dirty_record "sync"
5534         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5535         do_dirty_record "echo blah > $f"
5536         [[ $before -eq $after ]] && error "write wasn't cached"
5537         do_dirty_record "cancel_lru_locks osc"
5538         [[ $before -gt $after ]] ||
5539                 error "lock cancellation didn't lower dirty count"
5540         start_writeback
5541 }
5542 run_test 45 "osc io page accounting ============================"
5543
5544 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5545 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5546 # objects offset and an assert hit when an rpc was built with 1023's mapped
5547 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5548 test_46() {
5549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5550
5551         f="$DIR/f46"
5552         stop_writeback
5553         sync
5554         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5555         sync
5556         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5557         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5558         sync
5559         start_writeback
5560 }
5561 run_test 46 "dirtying a previously written page ================"
5562
5563 # test_47 is removed "Device nodes check" is moved to test_28
5564
5565 test_48a() { # bug 2399
5566         [ "$mds1_FSTYPE" = "zfs" ] &&
5567         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5568                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5569
5570         test_mkdir $DIR/$tdir
5571         cd $DIR/$tdir
5572         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5573         test_mkdir $DIR/$tdir
5574         touch foo || error "'touch foo' failed after recreating cwd"
5575         test_mkdir bar
5576         touch .foo || error "'touch .foo' failed after recreating cwd"
5577         test_mkdir .bar
5578         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5579         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5580         cd . || error "'cd .' failed after recreating cwd"
5581         mkdir . && error "'mkdir .' worked after recreating cwd"
5582         rmdir . && error "'rmdir .' worked after recreating cwd"
5583         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5584         cd .. || error "'cd ..' failed after recreating cwd"
5585 }
5586 run_test 48a "Access renamed working dir (should return errors)="
5587
5588 test_48b() { # bug 2399
5589         rm -rf $DIR/$tdir
5590         test_mkdir $DIR/$tdir
5591         cd $DIR/$tdir
5592         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5593         touch foo && error "'touch foo' worked after removing cwd"
5594         mkdir foo && error "'mkdir foo' worked after removing cwd"
5595         touch .foo && error "'touch .foo' worked after removing cwd"
5596         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5597         ls . > /dev/null && error "'ls .' worked after removing cwd"
5598         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5599         mkdir . && error "'mkdir .' worked after removing cwd"
5600         rmdir . && error "'rmdir .' worked after removing cwd"
5601         ln -s . foo && error "'ln -s .' worked after removing cwd"
5602         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5603 }
5604 run_test 48b "Access removed working dir (should return errors)="
5605
5606 test_48c() { # bug 2350
5607         #lctl set_param debug=-1
5608         #set -vx
5609         rm -rf $DIR/$tdir
5610         test_mkdir -p $DIR/$tdir/dir
5611         cd $DIR/$tdir/dir
5612         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5613         $TRACE touch foo && error "touch foo worked after removing cwd"
5614         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5615         touch .foo && error "touch .foo worked after removing cwd"
5616         mkdir .foo && error "mkdir .foo worked after removing cwd"
5617         $TRACE ls . && error "'ls .' worked after removing cwd"
5618         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5619         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5620         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5621         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5622         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5623 }
5624 run_test 48c "Access removed working subdir (should return errors)"
5625
5626 test_48d() { # bug 2350
5627         #lctl set_param debug=-1
5628         #set -vx
5629         rm -rf $DIR/$tdir
5630         test_mkdir -p $DIR/$tdir/dir
5631         cd $DIR/$tdir/dir
5632         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5633         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5634         $TRACE touch foo && error "'touch foo' worked after removing parent"
5635         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5636         touch .foo && error "'touch .foo' worked after removing parent"
5637         mkdir .foo && error "mkdir .foo worked after removing parent"
5638         $TRACE ls . && error "'ls .' worked after removing parent"
5639         $TRACE ls .. && error "'ls ..' worked after removing parent"
5640         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5641         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5642         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5643         true
5644 }
5645 run_test 48d "Access removed parent subdir (should return errors)"
5646
5647 test_48e() { # bug 4134
5648         #lctl set_param debug=-1
5649         #set -vx
5650         rm -rf $DIR/$tdir
5651         test_mkdir -p $DIR/$tdir/dir
5652         cd $DIR/$tdir/dir
5653         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5654         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5655         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5656         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5657         # On a buggy kernel addition of "touch foo" after cd .. will
5658         # produce kernel oops in lookup_hash_it
5659         touch ../foo && error "'cd ..' worked after recreate parent"
5660         cd $DIR
5661         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5662 }
5663 run_test 48e "Access to recreated parent subdir (should return errors)"
5664
5665 test_48f() {
5666         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5667                 skip "need MDS >= 2.13.55"
5668         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5669         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5670                 skip "needs different host for mdt1 mdt2"
5671         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5672
5673         $LFS mkdir -i0 $DIR/$tdir
5674         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5675
5676         for d in sub1 sub2 sub3; do
5677                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5678                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5679                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5680         done
5681
5682         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5683 }
5684 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5685
5686 test_49() { # LU-1030
5687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5688         remote_ost_nodsh && skip "remote OST with nodsh"
5689
5690         # get ost1 size - $FSNAME-OST0000
5691         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5692                 awk '{ print $4 }')
5693         # write 800M at maximum
5694         [[ $ost1_size -lt 2 ]] && ost1_size=2
5695         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5696
5697         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5698         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5699         local dd_pid=$!
5700
5701         # change max_pages_per_rpc while writing the file
5702         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5703         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5704         # loop until dd process exits
5705         while ps ax -opid | grep -wq $dd_pid; do
5706                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5707                 sleep $((RANDOM % 5 + 1))
5708         done
5709         # restore original max_pages_per_rpc
5710         $LCTL set_param $osc1_mppc=$orig_mppc
5711         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5712 }
5713 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5714
5715 test_50() {
5716         # bug 1485
5717         test_mkdir $DIR/$tdir
5718         cd $DIR/$tdir
5719         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5720 }
5721 run_test 50 "special situations: /proc symlinks  ==============="
5722
5723 test_51a() {    # was test_51
5724         # bug 1516 - create an empty entry right after ".." then split dir
5725         test_mkdir -c1 $DIR/$tdir
5726         touch $DIR/$tdir/foo
5727         $MCREATE $DIR/$tdir/bar
5728         rm $DIR/$tdir/foo
5729         createmany -m $DIR/$tdir/longfile 201
5730         FNUM=202
5731         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5732                 $MCREATE $DIR/$tdir/longfile$FNUM
5733                 FNUM=$(($FNUM + 1))
5734                 echo -n "+"
5735         done
5736         echo
5737         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5738 }
5739 run_test 51a "special situations: split htree with empty entry =="
5740
5741 cleanup_print_lfs_df () {
5742         trap 0
5743         $LFS df
5744         $LFS df -i
5745 }
5746
5747 test_51b() {
5748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5749
5750         local dir=$DIR/$tdir
5751         local nrdirs=$((65536 + 100))
5752
5753         # cleanup the directory
5754         rm -fr $dir
5755
5756         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5757
5758         $LFS df
5759         $LFS df -i
5760         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5761         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5762         [[ $numfree -lt $nrdirs ]] &&
5763                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5764
5765         # need to check free space for the directories as well
5766         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5767         numfree=$(( blkfree / $(fs_inode_ksize) ))
5768         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5769
5770         trap cleanup_print_lfs_df EXIT
5771
5772         # create files
5773         createmany -d $dir/d $nrdirs || {
5774                 unlinkmany $dir/d $nrdirs
5775                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5776         }
5777
5778         # really created :
5779         nrdirs=$(ls -U $dir | wc -l)
5780
5781         # unlink all but 100 subdirectories, then check it still works
5782         local left=100
5783         local delete=$((nrdirs - left))
5784
5785         $LFS df
5786         $LFS df -i
5787
5788         # for ldiskfs the nlink count should be 1, but this is OSD specific
5789         # and so this is listed for informational purposes only
5790         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5791         unlinkmany -d $dir/d $delete ||
5792                 error "unlink of first $delete subdirs failed"
5793
5794         echo "nlink between: $(stat -c %h $dir)"
5795         local found=$(ls -U $dir | wc -l)
5796         [ $found -ne $left ] &&
5797                 error "can't find subdirs: found only $found, expected $left"
5798
5799         unlinkmany -d $dir/d $delete $left ||
5800                 error "unlink of second $left subdirs failed"
5801         # regardless of whether the backing filesystem tracks nlink accurately
5802         # or not, the nlink count shouldn't be more than "." and ".." here
5803         local after=$(stat -c %h $dir)
5804         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5805                 echo "nlink after: $after"
5806
5807         cleanup_print_lfs_df
5808 }
5809 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5810
5811 test_51d() {
5812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5813         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5814         local qos_old
5815
5816         test_mkdir $DIR/$tdir
5817         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5818
5819         qos_old=$(do_facet mds1 \
5820                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5821         do_nodes $(comma_list $(mdts_nodes)) \
5822                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5823         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5824                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5825
5826         createmany -o $DIR/$tdir/t- 1000
5827         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5828         for ((n = 0; n < $OSTCOUNT; n++)); do
5829                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5830                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5831                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5832                             '($1 == '$n') { objs += 1 } \
5833                             END { printf("%0.0f", objs) }')
5834                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5835         done
5836         unlinkmany $DIR/$tdir/t- 1000
5837
5838         nlast=0
5839         for ((n = 0; n < $OSTCOUNT; n++)); do
5840                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5841                         { $LFS df && $LFS df -i &&
5842                         error "OST $n has fewer objects vs. OST $nlast" \
5843                               " (${objs[$n]} < ${objs[$nlast]}"; }
5844                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5845                         { $LFS df && $LFS df -i &&
5846                         error "OST $n has fewer objects vs. OST $nlast" \
5847                               " (${objs[$n]} < ${objs[$nlast]}"; }
5848
5849                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5850                         { $LFS df && $LFS df -i &&
5851                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5852                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5853                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5854                         { $LFS df && $LFS df -i &&
5855                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5856                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5857                 nlast=$n
5858         done
5859 }
5860 run_test 51d "check object distribution"
5861
5862 test_51e() {
5863         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5864                 skip_env "ldiskfs only test"
5865         fi
5866
5867         test_mkdir -c1 $DIR/$tdir
5868         test_mkdir -c1 $DIR/$tdir/d0
5869
5870         touch $DIR/$tdir/d0/foo
5871         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5872                 error "file exceed 65000 nlink limit!"
5873         unlinkmany $DIR/$tdir/d0/f- 65001
5874         return 0
5875 }
5876 run_test 51e "check file nlink limit"
5877
5878 test_51f() {
5879         test_mkdir $DIR/$tdir
5880
5881         local max=100000
5882         local ulimit_old=$(ulimit -n)
5883         local spare=20 # number of spare fd's for scripts/libraries, etc.
5884         local mdt=$($LFS getstripe -m $DIR/$tdir)
5885         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5886
5887         echo "MDT$mdt numfree=$numfree, max=$max"
5888         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5889         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5890                 while ! ulimit -n $((numfree + spare)); do
5891                         numfree=$((numfree * 3 / 4))
5892                 done
5893                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5894         else
5895                 echo "left ulimit at $ulimit_old"
5896         fi
5897
5898         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5899                 unlinkmany $DIR/$tdir/f $numfree
5900                 error "create+open $numfree files in $DIR/$tdir failed"
5901         }
5902         ulimit -n $ulimit_old
5903
5904         # if createmany exits at 120s there will be fewer than $numfree files
5905         unlinkmany $DIR/$tdir/f $numfree || true
5906 }
5907 run_test 51f "check many open files limit"
5908
5909 test_52a() {
5910         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5911         test_mkdir $DIR/$tdir
5912         touch $DIR/$tdir/foo
5913         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5914         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5915         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5916         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5917         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5918                                         error "link worked"
5919         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5920         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5921         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5922                                                      error "lsattr"
5923         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5924         cp -r $DIR/$tdir $TMP/
5925         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5926 }
5927 run_test 52a "append-only flag test (should return errors)"
5928
5929 test_52b() {
5930         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5931         test_mkdir $DIR/$tdir
5932         touch $DIR/$tdir/foo
5933         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5934         cat test > $DIR/$tdir/foo && error "cat test worked"
5935         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5936         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5937         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5938                                         error "link worked"
5939         echo foo >> $DIR/$tdir/foo && error "echo worked"
5940         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5941         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5942         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5943         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5944                                                         error "lsattr"
5945         chattr -i $DIR/$tdir/foo || error "chattr failed"
5946
5947         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5948 }
5949 run_test 52b "immutable flag test (should return errors) ======="
5950
5951 test_53() {
5952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5953         remote_mds_nodsh && skip "remote MDS with nodsh"
5954         remote_ost_nodsh && skip "remote OST with nodsh"
5955
5956         local param
5957         local param_seq
5958         local ostname
5959         local mds_last
5960         local mds_last_seq
5961         local ost_last
5962         local ost_last_seq
5963         local ost_last_id
5964         local ostnum
5965         local node
5966         local found=false
5967         local support_last_seq=true
5968
5969         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5970                 support_last_seq=false
5971
5972         # only test MDT0000
5973         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5974         local value
5975         for value in $(do_facet $SINGLEMDS \
5976                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5977                 param=$(echo ${value[0]} | cut -d "=" -f1)
5978                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5979
5980                 if $support_last_seq; then
5981                         param_seq=$(echo $param |
5982                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5983                         mds_last_seq=$(do_facet $SINGLEMDS \
5984                                        $LCTL get_param -n $param_seq)
5985                 fi
5986                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5987
5988                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5989                 node=$(facet_active_host ost$((ostnum+1)))
5990                 param="obdfilter.$ostname.last_id"
5991                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5992                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5993                         ost_last_id=$ost_last
5994
5995                         if $support_last_seq; then
5996                                 ost_last_id=$(echo $ost_last |
5997                                               awk -F':' '{print $2}' |
5998                                               sed -e "s/^0x//g")
5999                                 ost_last_seq=$(echo $ost_last |
6000                                                awk -F':' '{print $1}')
6001                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6002                         fi
6003
6004                         if [[ $ost_last_id != $mds_last ]]; then
6005                                 error "$ost_last_id != $mds_last"
6006                         else
6007                                 found=true
6008                                 break
6009                         fi
6010                 done
6011         done
6012         $found || error "can not match last_seq/last_id for $mdtosc"
6013         return 0
6014 }
6015 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6016
6017 test_54a() {
6018         perl -MSocket -e ';' || skip "no Socket perl module installed"
6019
6020         $SOCKETSERVER $DIR/socket ||
6021                 error "$SOCKETSERVER $DIR/socket failed: $?"
6022         $SOCKETCLIENT $DIR/socket ||
6023                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6024         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6025 }
6026 run_test 54a "unix domain socket test =========================="
6027
6028 test_54b() {
6029         f="$DIR/f54b"
6030         mknod $f c 1 3
6031         chmod 0666 $f
6032         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6033 }
6034 run_test 54b "char device works in lustre ======================"
6035
6036 find_loop_dev() {
6037         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6038         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6039         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6040
6041         for i in $(seq 3 7); do
6042                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6043                 LOOPDEV=$LOOPBASE$i
6044                 LOOPNUM=$i
6045                 break
6046         done
6047 }
6048
6049 cleanup_54c() {
6050         local rc=0
6051         loopdev="$DIR/loop54c"
6052
6053         trap 0
6054         $UMOUNT $DIR/$tdir || rc=$?
6055         losetup -d $loopdev || true
6056         losetup -d $LOOPDEV || true
6057         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6058         return $rc
6059 }
6060
6061 test_54c() {
6062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6063
6064         loopdev="$DIR/loop54c"
6065
6066         find_loop_dev
6067         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6068         trap cleanup_54c EXIT
6069         mknod $loopdev b 7 $LOOPNUM
6070         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6071         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6072         losetup $loopdev $DIR/$tfile ||
6073                 error "can't set up $loopdev for $DIR/$tfile"
6074         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6075         test_mkdir $DIR/$tdir
6076         mount -t ext2 $loopdev $DIR/$tdir ||
6077                 error "error mounting $loopdev on $DIR/$tdir"
6078         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6079                 error "dd write"
6080         df $DIR/$tdir
6081         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6082                 error "dd read"
6083         cleanup_54c
6084 }
6085 run_test 54c "block device works in lustre ====================="
6086
6087 test_54d() {
6088         local pipe="$DIR/$tfile.pipe"
6089         local string="aaaaaa"
6090
6091         mknod $pipe p
6092         echo -n "$string" > $pipe &
6093         local result=$(cat $pipe)
6094         [[ "$result" == "$string" ]] || error "$result != $string"
6095 }
6096 run_test 54d "fifo device works in lustre ======================"
6097
6098 test_54e() {
6099         f="$DIR/f54e"
6100         string="aaaaaa"
6101         cp -aL /dev/console $f
6102         echo $string > $f || error "echo $string to $f failed"
6103 }
6104 run_test 54e "console/tty device works in lustre ======================"
6105
6106 test_56a() {
6107         local numfiles=3
6108         local numdirs=2
6109         local dir=$DIR/$tdir
6110
6111         rm -rf $dir
6112         test_mkdir -p $dir/dir
6113         for i in $(seq $numfiles); do
6114                 touch $dir/file$i
6115                 touch $dir/dir/file$i
6116         done
6117
6118         local numcomp=$($LFS getstripe --component-count $dir)
6119
6120         [[ $numcomp == 0 ]] && numcomp=1
6121
6122         # test lfs getstripe with --recursive
6123         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6124
6125         [[ $filenum -eq $((numfiles * 2)) ]] ||
6126                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6127         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6128         [[ $filenum -eq $numfiles ]] ||
6129                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6130         echo "$LFS getstripe showed obdidx or l_ost_idx"
6131
6132         # test lfs getstripe with file instead of dir
6133         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6134         [[ $filenum -eq 1 ]] ||
6135                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6136         echo "$LFS getstripe file1 passed"
6137
6138         #test lfs getstripe with --verbose
6139         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6140         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6141                 error "$LFS getstripe --verbose $dir: "\
6142                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6143         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6144                 error "$LFS getstripe $dir: showed lmm_magic"
6145
6146         #test lfs getstripe with -v prints lmm_fid
6147         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6148         local countfids=$((numdirs + numfiles * numcomp))
6149         [[ $filenum -eq $countfids ]] ||
6150                 error "$LFS getstripe -v $dir: "\
6151                       "got $filenum want $countfids lmm_fid"
6152         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6153                 error "$LFS getstripe $dir: showed lmm_fid by default"
6154         echo "$LFS getstripe --verbose passed"
6155
6156         #check for FID information
6157         local fid1=$($LFS getstripe --fid $dir/file1)
6158         local fid2=$($LFS getstripe --verbose $dir/file1 |
6159                      awk '/lmm_fid: / { print $2; exit; }')
6160         local fid3=$($LFS path2fid $dir/file1)
6161
6162         [ "$fid1" != "$fid2" ] &&
6163                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6164         [ "$fid1" != "$fid3" ] &&
6165                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6166         echo "$LFS getstripe --fid passed"
6167
6168         #test lfs getstripe with --obd
6169         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6170                 error "$LFS getstripe --obd wrong_uuid: should return error"
6171
6172         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6173
6174         local ostidx=1
6175         local obduuid=$(ostuuid_from_index $ostidx)
6176         local found=$($LFS getstripe -r --obd $obduuid $dir |
6177                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6178
6179         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6180         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6181                 ((filenum--))
6182         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6183                 ((filenum--))
6184
6185         [[ $found -eq $filenum ]] ||
6186                 error "$LFS getstripe --obd: found $found expect $filenum"
6187         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6188                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6189                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6190                 error "$LFS getstripe --obd: should not show file on other obd"
6191         echo "$LFS getstripe --obd passed"
6192 }
6193 run_test 56a "check $LFS getstripe"
6194
6195 test_56b() {
6196         local dir=$DIR/$tdir
6197         local numdirs=3
6198
6199         test_mkdir $dir
6200         for i in $(seq $numdirs); do
6201                 test_mkdir $dir/dir$i
6202         done
6203
6204         # test lfs getdirstripe default mode is non-recursion, which is
6205         # different from lfs getstripe
6206         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6207
6208         [[ $dircnt -eq 1 ]] ||
6209                 error "$LFS getdirstripe: found $dircnt, not 1"
6210         dircnt=$($LFS getdirstripe --recursive $dir |
6211                 grep -c lmv_stripe_count)
6212         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6213                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6214 }
6215 run_test 56b "check $LFS getdirstripe"
6216
6217 test_56c() {
6218         remote_ost_nodsh && skip "remote OST with nodsh"
6219
6220         local ost_idx=0
6221         local ost_name=$(ostname_from_index $ost_idx)
6222         local old_status=$(ost_dev_status $ost_idx)
6223         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6224
6225         [[ -z "$old_status" ]] ||
6226                 skip_env "OST $ost_name is in $old_status status"
6227
6228         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6229         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6230                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6231         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6232                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6233                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6234         fi
6235
6236         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6237                 error "$LFS df -v showing inactive devices"
6238         sleep_maxage
6239
6240         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6241
6242         [[ "$new_status" =~ "D" ]] ||
6243                 error "$ost_name status is '$new_status', missing 'D'"
6244         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6245                 [[ "$new_status" =~ "N" ]] ||
6246                         error "$ost_name status is '$new_status', missing 'N'"
6247         fi
6248         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6249                 [[ "$new_status" =~ "f" ]] ||
6250                         error "$ost_name status is '$new_status', missing 'f'"
6251         fi
6252
6253         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6254         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6255                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6256         [[ -z "$p" ]] && restore_lustre_params < $p || true
6257         sleep_maxage
6258
6259         new_status=$(ost_dev_status $ost_idx)
6260         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6261                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6262         # can't check 'f' as devices may actually be on flash
6263 }
6264 run_test 56c "check 'lfs df' showing device status"
6265
6266 test_56d() {
6267         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6268         local osts=$($LFS df -v $MOUNT | grep -c OST)
6269
6270         $LFS df $MOUNT
6271
6272         (( mdts == MDSCOUNT )) ||
6273                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6274         (( osts == OSTCOUNT )) ||
6275                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6276 }
6277 run_test 56d "'lfs df -v' prints only configured devices"
6278
6279 test_56e() {
6280         err_enoent=2 # No such file or directory
6281         err_eopnotsupp=95 # Operation not supported
6282
6283         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6284         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6285
6286         # Check for handling of path not exists
6287         output=$($LFS df $enoent_mnt 2>&1)
6288         ret=$?
6289
6290         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6291         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6292                 error "expect failure $err_enoent, not $ret"
6293
6294         # Check for handling of non-Lustre FS
6295         output=$($LFS df $notsup_mnt)
6296         ret=$?
6297
6298         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6299         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6300                 error "expect success $err_eopnotsupp, not $ret"
6301
6302         # Check for multiple LustreFS argument
6303         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6304         ret=$?
6305
6306         [[ $output -eq 3 && $ret -eq 0 ]] ||
6307                 error "expect success 3, not $output, rc = $ret"
6308
6309         # Check for correct non-Lustre FS handling among multiple
6310         # LustreFS argument
6311         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6312                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6313         ret=$?
6314
6315         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6316                 error "expect success 2, not $output, rc = $ret"
6317 }
6318 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6319
6320 NUMFILES=3
6321 NUMDIRS=3
6322 setup_56() {
6323         local local_tdir="$1"
6324         local local_numfiles="$2"
6325         local local_numdirs="$3"
6326         local dir_params="$4"
6327         local dir_stripe_params="$5"
6328
6329         if [ ! -d "$local_tdir" ] ; then
6330                 test_mkdir -p $dir_stripe_params $local_tdir
6331                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6332                 for i in $(seq $local_numfiles) ; do
6333                         touch $local_tdir/file$i
6334                 done
6335                 for i in $(seq $local_numdirs) ; do
6336                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6337                         for j in $(seq $local_numfiles) ; do
6338                                 touch $local_tdir/dir$i/file$j
6339                         done
6340                 done
6341         fi
6342 }
6343
6344 setup_56_special() {
6345         local local_tdir=$1
6346         local local_numfiles=$2
6347         local local_numdirs=$3
6348
6349         setup_56 $local_tdir $local_numfiles $local_numdirs
6350
6351         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6352                 for i in $(seq $local_numfiles) ; do
6353                         mknod $local_tdir/loop${i}b b 7 $i
6354                         mknod $local_tdir/null${i}c c 1 3
6355                         ln -s $local_tdir/file1 $local_tdir/link${i}
6356                 done
6357                 for i in $(seq $local_numdirs) ; do
6358                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6359                         mknod $local_tdir/dir$i/null${i}c c 1 3
6360                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6361                 done
6362         fi
6363 }
6364
6365 test_56g() {
6366         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6367         local expected=$(($NUMDIRS + 2))
6368
6369         setup_56 $dir $NUMFILES $NUMDIRS
6370
6371         # test lfs find with -name
6372         for i in $(seq $NUMFILES) ; do
6373                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6374
6375                 [ $nums -eq $expected ] ||
6376                         error "lfs find -name '*$i' $dir wrong: "\
6377                               "found $nums, expected $expected"
6378         done
6379 }
6380 run_test 56g "check lfs find -name"
6381
6382 test_56h() {
6383         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6384         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6385
6386         setup_56 $dir $NUMFILES $NUMDIRS
6387
6388         # test lfs find with ! -name
6389         for i in $(seq $NUMFILES) ; do
6390                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6391
6392                 [ $nums -eq $expected ] ||
6393                         error "lfs find ! -name '*$i' $dir wrong: "\
6394                               "found $nums, expected $expected"
6395         done
6396 }
6397 run_test 56h "check lfs find ! -name"
6398
6399 test_56i() {
6400         local dir=$DIR/$tdir
6401
6402         test_mkdir $dir
6403
6404         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6405         local out=$($cmd)
6406
6407         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6408 }
6409 run_test 56i "check 'lfs find -ost UUID' skips directories"
6410
6411 test_56j() {
6412         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6413
6414         setup_56_special $dir $NUMFILES $NUMDIRS
6415
6416         local expected=$((NUMDIRS + 1))
6417         local cmd="$LFS find -type d $dir"
6418         local nums=$($cmd | wc -l)
6419
6420         [ $nums -eq $expected ] ||
6421                 error "'$cmd' wrong: found $nums, expected $expected"
6422 }
6423 run_test 56j "check lfs find -type d"
6424
6425 test_56k() {
6426         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6427
6428         setup_56_special $dir $NUMFILES $NUMDIRS
6429
6430         local expected=$(((NUMDIRS + 1) * NUMFILES))
6431         local cmd="$LFS find -type f $dir"
6432         local nums=$($cmd | wc -l)
6433
6434         [ $nums -eq $expected ] ||
6435                 error "'$cmd' wrong: found $nums, expected $expected"
6436 }
6437 run_test 56k "check lfs find -type f"
6438
6439 test_56l() {
6440         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6441
6442         setup_56_special $dir $NUMFILES $NUMDIRS
6443
6444         local expected=$((NUMDIRS + NUMFILES))
6445         local cmd="$LFS find -type b $dir"
6446         local nums=$($cmd | wc -l)
6447
6448         [ $nums -eq $expected ] ||
6449                 error "'$cmd' wrong: found $nums, expected $expected"
6450 }
6451 run_test 56l "check lfs find -type b"
6452
6453 test_56m() {
6454         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6455
6456         setup_56_special $dir $NUMFILES $NUMDIRS
6457
6458         local expected=$((NUMDIRS + NUMFILES))
6459         local cmd="$LFS find -type c $dir"
6460         local nums=$($cmd | wc -l)
6461         [ $nums -eq $expected ] ||
6462                 error "'$cmd' wrong: found $nums, expected $expected"
6463 }
6464 run_test 56m "check lfs find -type c"
6465
6466 test_56n() {
6467         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6468         setup_56_special $dir $NUMFILES $NUMDIRS
6469
6470         local expected=$((NUMDIRS + NUMFILES))
6471         local cmd="$LFS find -type l $dir"
6472         local nums=$($cmd | wc -l)
6473
6474         [ $nums -eq $expected ] ||
6475                 error "'$cmd' wrong: found $nums, expected $expected"
6476 }
6477 run_test 56n "check lfs find -type l"
6478
6479 test_56o() {
6480         local dir=$DIR/$tdir
6481
6482         setup_56 $dir $NUMFILES $NUMDIRS
6483         utime $dir/file1 > /dev/null || error "utime (1)"
6484         utime $dir/file2 > /dev/null || error "utime (2)"
6485         utime $dir/dir1 > /dev/null || error "utime (3)"
6486         utime $dir/dir2 > /dev/null || error "utime (4)"
6487         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6488         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6489
6490         local expected=4
6491         local nums=$($LFS find -mtime +0 $dir | wc -l)
6492
6493         [ $nums -eq $expected ] ||
6494                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6495
6496         expected=12
6497         cmd="$LFS find -mtime 0 $dir"
6498         nums=$($cmd | wc -l)
6499         [ $nums -eq $expected ] ||
6500                 error "'$cmd' wrong: found $nums, expected $expected"
6501 }
6502 run_test 56o "check lfs find -mtime for old files"
6503
6504 test_56ob() {
6505         local dir=$DIR/$tdir
6506         local expected=1
6507         local count=0
6508
6509         # just to make sure there is something that won't be found
6510         test_mkdir $dir
6511         touch $dir/$tfile.now
6512
6513         for age in year week day hour min; do
6514                 count=$((count + 1))
6515
6516                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6517                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6518                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6519
6520                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6521                 local nums=$($cmd | wc -l)
6522                 [ $nums -eq $expected ] ||
6523                         error "'$cmd' wrong: found $nums, expected $expected"
6524
6525                 cmd="$LFS find $dir -atime $count${age:0:1}"
6526                 nums=$($cmd | wc -l)
6527                 [ $nums -eq $expected ] ||
6528                         error "'$cmd' wrong: found $nums, expected $expected"
6529         done
6530
6531         sleep 2
6532         cmd="$LFS find $dir -ctime +1s -type f"
6533         nums=$($cmd | wc -l)
6534         (( $nums == $count * 2 + 1)) ||
6535                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6536 }
6537 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6538
6539 test_newerXY_base() {
6540         local x=$1
6541         local y=$2
6542         local dir=$DIR/$tdir
6543         local ref
6544         local negref
6545
6546         if [ $y == "t" ]; then
6547                 if [ $x == "b" ]; then
6548                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6549                 else
6550                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6551                 fi
6552         else
6553                 ref=$DIR/$tfile.newer.$x$y
6554                 touch $ref || error "touch $ref failed"
6555         fi
6556
6557         echo "before = $ref"
6558         sleep 2
6559         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6560         sleep 2
6561         if [ $y == "t" ]; then
6562                 if [ $x == "b" ]; then
6563                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6564                 else
6565                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6566                 fi
6567         else
6568                 negref=$DIR/$tfile.negnewer.$x$y
6569                 touch $negref || error "touch $negref failed"
6570         fi
6571
6572         echo "after = $negref"
6573         local cmd="$LFS find $dir -newer$x$y $ref"
6574         local nums=$(eval $cmd | wc -l)
6575         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6576
6577         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6578                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6579
6580         cmd="$LFS find $dir ! -newer$x$y $negref"
6581         nums=$(eval $cmd | wc -l)
6582         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6583                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6584
6585         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6586         nums=$(eval $cmd | wc -l)
6587         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6588                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6589
6590         rm -rf $DIR/*
6591 }
6592
6593 test_56oc() {
6594         test_newerXY_base "a" "a"
6595         test_newerXY_base "a" "m"
6596         test_newerXY_base "a" "c"
6597         test_newerXY_base "m" "a"
6598         test_newerXY_base "m" "m"
6599         test_newerXY_base "m" "c"
6600         test_newerXY_base "c" "a"
6601         test_newerXY_base "c" "m"
6602         test_newerXY_base "c" "c"
6603
6604         [[ -n "$sles_version" ]] &&
6605                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6606
6607         test_newerXY_base "a" "t"
6608         test_newerXY_base "m" "t"
6609         test_newerXY_base "c" "t"
6610
6611         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6612            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6613                 ! btime_supported && echo "btime unsupported" && return 0
6614
6615         test_newerXY_base "b" "b"
6616         test_newerXY_base "b" "t"
6617 }
6618 run_test 56oc "check lfs find -newerXY work"
6619
6620 btime_supported() {
6621         local dir=$DIR/$tdir
6622         local rc
6623
6624         mkdir -p $dir
6625         touch $dir/$tfile
6626         $LFS find $dir -btime -1d -type f
6627         rc=$?
6628         rm -rf $dir
6629         return $rc
6630 }
6631
6632 test_56od() {
6633         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6634                 ! btime_supported && skip "btime unsupported on MDS"
6635
6636         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6637                 ! btime_supported && skip "btime unsupported on clients"
6638
6639         local dir=$DIR/$tdir
6640         local ref=$DIR/$tfile.ref
6641         local negref=$DIR/$tfile.negref
6642
6643         mkdir $dir || error "mkdir $dir failed"
6644         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6645         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6646         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6647         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6648         touch $ref || error "touch $ref failed"
6649         # sleep 3 seconds at least
6650         sleep 3
6651
6652         local before=$(do_facet mds1 date +%s)
6653         local skew=$(($(date +%s) - before + 1))
6654
6655         if (( skew < 0 && skew > -5 )); then
6656                 sleep $((0 - skew + 1))
6657                 skew=0
6658         fi
6659
6660         # Set the dir stripe params to limit files all on MDT0,
6661         # otherwise we need to calc the max clock skew between
6662         # the client and MDTs.
6663         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6664         sleep 2
6665         touch $negref || error "touch $negref failed"
6666
6667         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6668         local nums=$($cmd | wc -l)
6669         local expected=$(((NUMFILES + 1) * NUMDIRS))
6670
6671         [ $nums -eq $expected ] ||
6672                 error "'$cmd' wrong: found $nums, expected $expected"
6673
6674         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6675         nums=$($cmd | wc -l)
6676         expected=$((NUMFILES + 1))
6677         [ $nums -eq $expected ] ||
6678                 error "'$cmd' wrong: found $nums, expected $expected"
6679
6680         [ $skew -lt 0 ] && return
6681
6682         local after=$(do_facet mds1 date +%s)
6683         local age=$((after - before + 1 + skew))
6684
6685         cmd="$LFS find $dir -btime -${age}s -type f"
6686         nums=$($cmd | wc -l)
6687         expected=$(((NUMFILES + 1) * NUMDIRS))
6688
6689         echo "Clock skew between client and server: $skew, age:$age"
6690         [ $nums -eq $expected ] ||
6691                 error "'$cmd' wrong: found $nums, expected $expected"
6692
6693         expected=$(($NUMDIRS + 1))
6694         cmd="$LFS find $dir -btime -${age}s -type d"
6695         nums=$($cmd | wc -l)
6696         [ $nums -eq $expected ] ||
6697                 error "'$cmd' wrong: found $nums, expected $expected"
6698         rm -f $ref $negref || error "Failed to remove $ref $negref"
6699 }
6700 run_test 56od "check lfs find -btime with units"
6701
6702 test_56p() {
6703         [ $RUNAS_ID -eq $UID ] &&
6704                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6705
6706         local dir=$DIR/$tdir
6707
6708         setup_56 $dir $NUMFILES $NUMDIRS
6709         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6710
6711         local expected=$NUMFILES
6712         local cmd="$LFS find -uid $RUNAS_ID $dir"
6713         local nums=$($cmd | wc -l)
6714
6715         [ $nums -eq $expected ] ||
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717
6718         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6719         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6720         nums=$($cmd | wc -l)
6721         [ $nums -eq $expected ] ||
6722                 error "'$cmd' wrong: found $nums, expected $expected"
6723 }
6724 run_test 56p "check lfs find -uid and ! -uid"
6725
6726 test_56q() {
6727         [ $RUNAS_ID -eq $UID ] &&
6728                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6729
6730         local dir=$DIR/$tdir
6731
6732         setup_56 $dir $NUMFILES $NUMDIRS
6733         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6734
6735         local expected=$NUMFILES
6736         local cmd="$LFS find -gid $RUNAS_GID $dir"
6737         local nums=$($cmd | wc -l)
6738
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741
6742         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6743         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747 }
6748 run_test 56q "check lfs find -gid and ! -gid"
6749
6750 test_56r() {
6751         local dir=$DIR/$tdir
6752
6753         setup_56 $dir $NUMFILES $NUMDIRS
6754
6755         local expected=12
6756         local cmd="$LFS find -size 0 -type f -lazy $dir"
6757         local nums=$($cmd | wc -l)
6758
6759         [ $nums -eq $expected ] ||
6760                 error "'$cmd' wrong: found $nums, expected $expected"
6761         cmd="$LFS find -size 0 -type f $dir"
6762         nums=$($cmd | wc -l)
6763         [ $nums -eq $expected ] ||
6764                 error "'$cmd' wrong: found $nums, expected $expected"
6765
6766         expected=0
6767         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6768         nums=$($cmd | wc -l)
6769         [ $nums -eq $expected ] ||
6770                 error "'$cmd' wrong: found $nums, expected $expected"
6771         cmd="$LFS find ! -size 0 -type f $dir"
6772         nums=$($cmd | wc -l)
6773         [ $nums -eq $expected ] ||
6774                 error "'$cmd' wrong: found $nums, expected $expected"
6775
6776         echo "test" > $dir/$tfile
6777         echo "test2" > $dir/$tfile.2 && sync
6778         expected=1
6779         cmd="$LFS find -size 5 -type f -lazy $dir"
6780         nums=$($cmd | wc -l)
6781         [ $nums -eq $expected ] ||
6782                 error "'$cmd' wrong: found $nums, expected $expected"
6783         cmd="$LFS find -size 5 -type f $dir"
6784         nums=$($cmd | wc -l)
6785         [ $nums -eq $expected ] ||
6786                 error "'$cmd' wrong: found $nums, expected $expected"
6787
6788         expected=1
6789         cmd="$LFS find -size +5 -type f -lazy $dir"
6790         nums=$($cmd | wc -l)
6791         [ $nums -eq $expected ] ||
6792                 error "'$cmd' wrong: found $nums, expected $expected"
6793         cmd="$LFS find -size +5 -type f $dir"
6794         nums=$($cmd | wc -l)
6795         [ $nums -eq $expected ] ||
6796                 error "'$cmd' wrong: found $nums, expected $expected"
6797
6798         expected=2
6799         cmd="$LFS find -size +0 -type f -lazy $dir"
6800         nums=$($cmd | wc -l)
6801         [ $nums -eq $expected ] ||
6802                 error "'$cmd' wrong: found $nums, expected $expected"
6803         cmd="$LFS find -size +0 -type f $dir"
6804         nums=$($cmd | wc -l)
6805         [ $nums -eq $expected ] ||
6806                 error "'$cmd' wrong: found $nums, expected $expected"
6807
6808         expected=2
6809         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6810         nums=$($cmd | wc -l)
6811         [ $nums -eq $expected ] ||
6812                 error "'$cmd' wrong: found $nums, expected $expected"
6813         cmd="$LFS find ! -size -5 -type f $dir"
6814         nums=$($cmd | wc -l)
6815         [ $nums -eq $expected ] ||
6816                 error "'$cmd' wrong: found $nums, expected $expected"
6817
6818         expected=12
6819         cmd="$LFS find -size -5 -type f -lazy $dir"
6820         nums=$($cmd | wc -l)
6821         [ $nums -eq $expected ] ||
6822                 error "'$cmd' wrong: found $nums, expected $expected"
6823         cmd="$LFS find -size -5 -type f $dir"
6824         nums=$($cmd | wc -l)
6825         [ $nums -eq $expected ] ||
6826                 error "'$cmd' wrong: found $nums, expected $expected"
6827 }
6828 run_test 56r "check lfs find -size works"
6829
6830 test_56ra_sub() {
6831         local expected=$1
6832         local glimpses=$2
6833         local cmd="$3"
6834
6835         cancel_lru_locks $OSC
6836
6837         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6838         local nums=$($cmd | wc -l)
6839
6840         [ $nums -eq $expected ] ||
6841                 error "'$cmd' wrong: found $nums, expected $expected"
6842
6843         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6844
6845         if (( rpcs_before + glimpses != rpcs_after )); then
6846                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6847                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6848
6849                 if [[ $glimpses == 0 ]]; then
6850                         error "'$cmd' should not send glimpse RPCs to OST"
6851                 else
6852                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6853                 fi
6854         fi
6855 }
6856
6857 test_56ra() {
6858         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6859                 skip "MDS < 2.12.58 doesn't return LSOM data"
6860         local dir=$DIR/$tdir
6861         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6862
6863         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6864
6865         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6866         $LCTL set_param -n llite.*.statahead_agl=0
6867         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6868
6869         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6870         # open and close all files to ensure LSOM is updated
6871         cancel_lru_locks $OSC
6872         find $dir -type f | xargs cat > /dev/null
6873
6874         #   expect_found  glimpse_rpcs  command_to_run
6875         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6876         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6877         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6878         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6879
6880         echo "test" > $dir/$tfile
6881         echo "test2" > $dir/$tfile.2 && sync
6882         cancel_lru_locks $OSC
6883         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6884
6885         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6886         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6887         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6888         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6889
6890         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6891         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6892         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6893         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6894         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6895         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6896 }
6897 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6898
6899 test_56rb() {
6900         local dir=$DIR/$tdir
6901         local tmp=$TMP/$tfile.log
6902         local mdt_idx;
6903
6904         test_mkdir -p $dir || error "failed to mkdir $dir"
6905         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6906                 error "failed to setstripe $dir/$tfile"
6907         mdt_idx=$($LFS getdirstripe -i $dir)
6908         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6909
6910         stack_trap "rm -f $tmp" EXIT
6911         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6912         ! grep -q obd_uuid $tmp ||
6913                 error "failed to find --size +100K --ost 0 $dir"
6914         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6915         ! grep -q obd_uuid $tmp ||
6916                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6917 }
6918 run_test 56rb "check lfs find --size --ost/--mdt works"
6919
6920 test_56rc() {
6921         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6922         local dir=$DIR/$tdir
6923         local found
6924
6925         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6926         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6927         (( $MDSCOUNT > 2 )) &&
6928                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6929         mkdir $dir/$tdir-{1..10}
6930         touch $dir/$tfile-{1..10}
6931
6932         found=$($LFS find $dir --mdt-count 2 | wc -l)
6933         expect=11
6934         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6935
6936         found=$($LFS find $dir -T +1 | wc -l)
6937         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6938         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6939
6940         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6941         expect=11
6942         (( $found == $expect )) || error "found $found all_char, expect $expect"
6943
6944         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6945         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6946         (( $found == $expect )) || error "found $found all_char, expect $expect"
6947 }
6948 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6949
6950 test_56s() { # LU-611 #LU-9369
6951         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6952
6953         local dir=$DIR/$tdir
6954         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6955
6956         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6957         for i in $(seq $NUMDIRS); do
6958                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6959         done
6960
6961         local expected=$NUMDIRS
6962         local cmd="$LFS find -c $OSTCOUNT $dir"
6963         local nums=$($cmd | wc -l)
6964
6965         [ $nums -eq $expected ] || {
6966                 $LFS getstripe -R $dir
6967                 error "'$cmd' wrong: found $nums, expected $expected"
6968         }
6969
6970         expected=$((NUMDIRS + onestripe))
6971         cmd="$LFS find -stripe-count +0 -type f $dir"
6972         nums=$($cmd | wc -l)
6973         [ $nums -eq $expected ] || {
6974                 $LFS getstripe -R $dir
6975                 error "'$cmd' wrong: found $nums, expected $expected"
6976         }
6977
6978         expected=$onestripe
6979         cmd="$LFS find -stripe-count 1 -type f $dir"
6980         nums=$($cmd | wc -l)
6981         [ $nums -eq $expected ] || {
6982                 $LFS getstripe -R $dir
6983                 error "'$cmd' wrong: found $nums, expected $expected"
6984         }
6985
6986         cmd="$LFS find -stripe-count -2 -type f $dir"
6987         nums=$($cmd | wc -l)
6988         [ $nums -eq $expected ] || {
6989                 $LFS getstripe -R $dir
6990                 error "'$cmd' wrong: found $nums, expected $expected"
6991         }
6992
6993         expected=0
6994         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6995         nums=$($cmd | wc -l)
6996         [ $nums -eq $expected ] || {
6997                 $LFS getstripe -R $dir
6998                 error "'$cmd' wrong: found $nums, expected $expected"
6999         }
7000 }
7001 run_test 56s "check lfs find -stripe-count works"
7002
7003 test_56t() { # LU-611 #LU-9369
7004         local dir=$DIR/$tdir
7005
7006         setup_56 $dir 0 $NUMDIRS
7007         for i in $(seq $NUMDIRS); do
7008                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7009         done
7010
7011         local expected=$NUMDIRS
7012         local cmd="$LFS find -S 8M $dir"
7013         local nums=$($cmd | wc -l)
7014
7015         [ $nums -eq $expected ] || {
7016                 $LFS getstripe -R $dir
7017                 error "'$cmd' wrong: found $nums, expected $expected"
7018         }
7019         rm -rf $dir
7020
7021         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7022
7023         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7024
7025         expected=$(((NUMDIRS + 1) * NUMFILES))
7026         cmd="$LFS find -stripe-size 512k -type f $dir"
7027         nums=$($cmd | wc -l)
7028         [ $nums -eq $expected ] ||
7029                 error "'$cmd' wrong: found $nums, expected $expected"
7030
7031         cmd="$LFS find -stripe-size +320k -type f $dir"
7032         nums=$($cmd | wc -l)
7033         [ $nums -eq $expected ] ||
7034                 error "'$cmd' wrong: found $nums, expected $expected"
7035
7036         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7037         cmd="$LFS find -stripe-size +200k -type f $dir"
7038         nums=$($cmd | wc -l)
7039         [ $nums -eq $expected ] ||
7040                 error "'$cmd' wrong: found $nums, expected $expected"
7041
7042         cmd="$LFS find -stripe-size -640k -type f $dir"
7043         nums=$($cmd | wc -l)
7044         [ $nums -eq $expected ] ||
7045                 error "'$cmd' wrong: found $nums, expected $expected"
7046
7047         expected=4
7048         cmd="$LFS find -stripe-size 256k -type f $dir"
7049         nums=$($cmd | wc -l)
7050         [ $nums -eq $expected ] ||
7051                 error "'$cmd' wrong: found $nums, expected $expected"
7052
7053         cmd="$LFS find -stripe-size -320k -type f $dir"
7054         nums=$($cmd | wc -l)
7055         [ $nums -eq $expected ] ||
7056                 error "'$cmd' wrong: found $nums, expected $expected"
7057
7058         expected=0
7059         cmd="$LFS find -stripe-size 1024k -type f $dir"
7060         nums=$($cmd | wc -l)
7061         [ $nums -eq $expected ] ||
7062                 error "'$cmd' wrong: found $nums, expected $expected"
7063 }
7064 run_test 56t "check lfs find -stripe-size works"
7065
7066 test_56u() { # LU-611
7067         local dir=$DIR/$tdir
7068
7069         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7070
7071         if [[ $OSTCOUNT -gt 1 ]]; then
7072                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7073                 onestripe=4
7074         else
7075                 onestripe=0
7076         fi
7077
7078         local expected=$(((NUMDIRS + 1) * NUMFILES))
7079         local cmd="$LFS find -stripe-index 0 -type f $dir"
7080         local nums=$($cmd | wc -l)
7081
7082         [ $nums -eq $expected ] ||
7083                 error "'$cmd' wrong: found $nums, expected $expected"
7084
7085         expected=$onestripe
7086         cmd="$LFS find -stripe-index 1 -type f $dir"
7087         nums=$($cmd | wc -l)
7088         [ $nums -eq $expected ] ||
7089                 error "'$cmd' wrong: found $nums, expected $expected"
7090
7091         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7092         nums=$($cmd | wc -l)
7093         [ $nums -eq $expected ] ||
7094                 error "'$cmd' wrong: found $nums, expected $expected"
7095
7096         expected=0
7097         # This should produce an error and not return any files
7098         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7099         nums=$($cmd 2>/dev/null | wc -l)
7100         [ $nums -eq $expected ] ||
7101                 error "'$cmd' wrong: found $nums, expected $expected"
7102
7103         if [[ $OSTCOUNT -gt 1 ]]; then
7104                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7105                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7106                 nums=$($cmd | wc -l)
7107                 [ $nums -eq $expected ] ||
7108                         error "'$cmd' wrong: found $nums, expected $expected"
7109         fi
7110 }
7111 run_test 56u "check lfs find -stripe-index works"
7112
7113 test_56v() {
7114         local mdt_idx=0
7115         local dir=$DIR/$tdir
7116
7117         setup_56 $dir $NUMFILES $NUMDIRS
7118
7119         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7120         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7121
7122         for file in $($LFS find -m $UUID $dir); do
7123                 file_midx=$($LFS getstripe -m $file)
7124                 [ $file_midx -eq $mdt_idx ] ||
7125                         error "lfs find -m $UUID != getstripe -m $file_midx"
7126         done
7127 }
7128 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7129
7130 test_56w() {
7131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7133
7134         local dir=$DIR/$tdir
7135
7136         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7137
7138         local stripe_size=$($LFS getstripe -S -d $dir) ||
7139                 error "$LFS getstripe -S -d $dir failed"
7140         stripe_size=${stripe_size%% *}
7141
7142         local file_size=$((stripe_size * OSTCOUNT))
7143         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7144         local required_space=$((file_num * file_size))
7145         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7146                            head -n1)
7147         [[ $free_space -le $((required_space / 1024)) ]] &&
7148                 skip_env "need $required_space, have $free_space kbytes"
7149
7150         local dd_bs=65536
7151         local dd_count=$((file_size / dd_bs))
7152
7153         # write data into the files
7154         local i
7155         local j
7156         local file
7157
7158         for i in $(seq $NUMFILES); do
7159                 file=$dir/file$i
7160                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7161                         error "write data into $file failed"
7162         done
7163         for i in $(seq $NUMDIRS); do
7164                 for j in $(seq $NUMFILES); do
7165                         file=$dir/dir$i/file$j
7166                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7167                                 error "write data into $file failed"
7168                 done
7169         done
7170
7171         # $LFS_MIGRATE will fail if hard link migration is unsupported
7172         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7173                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7174                         error "creating links to $dir/dir1/file1 failed"
7175         fi
7176
7177         local expected=-1
7178
7179         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7180
7181         # lfs_migrate file
7182         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7183
7184         echo "$cmd"
7185         eval $cmd || error "$cmd failed"
7186
7187         check_stripe_count $dir/file1 $expected
7188
7189         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7190         then
7191                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7192                 # OST 1 if it is on OST 0. This file is small enough to
7193                 # be on only one stripe.
7194                 file=$dir/migr_1_ost
7195                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7196                         error "write data into $file failed"
7197                 local obdidx=$($LFS getstripe -i $file)
7198                 local oldmd5=$(md5sum $file)
7199                 local newobdidx=0
7200
7201                 [[ $obdidx -eq 0 ]] && newobdidx=1
7202                 cmd="$LFS migrate -i $newobdidx $file"
7203                 echo $cmd
7204                 eval $cmd || error "$cmd failed"
7205
7206                 local realobdix=$($LFS getstripe -i $file)
7207                 local newmd5=$(md5sum $file)
7208
7209                 [[ $newobdidx -ne $realobdix ]] &&
7210                         error "new OST is different (was=$obdidx, "\
7211                               "wanted=$newobdidx, got=$realobdix)"
7212                 [[ "$oldmd5" != "$newmd5" ]] &&
7213                         error "md5sum differ: $oldmd5, $newmd5"
7214         fi
7215
7216         # lfs_migrate dir
7217         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7218         echo "$cmd"
7219         eval $cmd || error "$cmd failed"
7220
7221         for j in $(seq $NUMFILES); do
7222                 check_stripe_count $dir/dir1/file$j $expected
7223         done
7224
7225         # lfs_migrate works with lfs find
7226         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7227              $LFS_MIGRATE -y -c $expected"
7228         echo "$cmd"
7229         eval $cmd || error "$cmd failed"
7230
7231         for i in $(seq 2 $NUMFILES); do
7232                 check_stripe_count $dir/file$i $expected
7233         done
7234         for i in $(seq 2 $NUMDIRS); do
7235                 for j in $(seq $NUMFILES); do
7236                 check_stripe_count $dir/dir$i/file$j $expected
7237                 done
7238         done
7239 }
7240 run_test 56w "check lfs_migrate -c stripe_count works"
7241
7242 test_56wb() {
7243         local file1=$DIR/$tdir/file1
7244         local create_pool=false
7245         local initial_pool=$($LFS getstripe -p $DIR)
7246         local pool_list=()
7247         local pool=""
7248
7249         echo -n "Creating test dir..."
7250         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7251         echo "done."
7252
7253         echo -n "Creating test file..."
7254         touch $file1 || error "cannot create file"
7255         echo "done."
7256
7257         echo -n "Detecting existing pools..."
7258         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7259
7260         if [ ${#pool_list[@]} -gt 0 ]; then
7261                 echo "${pool_list[@]}"
7262                 for thispool in "${pool_list[@]}"; do
7263                         if [[ -z "$initial_pool" ||
7264                               "$initial_pool" != "$thispool" ]]; then
7265                                 pool="$thispool"
7266                                 echo "Using existing pool '$pool'"
7267                                 break
7268                         fi
7269                 done
7270         else
7271                 echo "none detected."
7272         fi
7273         if [ -z "$pool" ]; then
7274                 pool=${POOL:-testpool}
7275                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7276                 echo -n "Creating pool '$pool'..."
7277                 create_pool=true
7278                 pool_add $pool &> /dev/null ||
7279                         error "pool_add failed"
7280                 echo "done."
7281
7282                 echo -n "Adding target to pool..."
7283                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7284                         error "pool_add_targets failed"
7285                 echo "done."
7286         fi
7287
7288         echo -n "Setting pool using -p option..."
7289         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7290                 error "migrate failed rc = $?"
7291         echo "done."
7292
7293         echo -n "Verifying test file is in pool after migrating..."
7294         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7295                 error "file was not migrated to pool $pool"
7296         echo "done."
7297
7298         echo -n "Removing test file from pool '$pool'..."
7299         # "lfs migrate $file" won't remove the file from the pool
7300         # until some striping information is changed.
7301         $LFS migrate -c 1 $file1 &> /dev/null ||
7302                 error "cannot remove from pool"
7303         [ "$($LFS getstripe -p $file1)" ] &&
7304                 error "pool still set"
7305         echo "done."
7306
7307         echo -n "Setting pool using --pool option..."
7308         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7309                 error "migrate failed rc = $?"
7310         echo "done."
7311
7312         # Clean up
7313         rm -f $file1
7314         if $create_pool; then
7315                 destroy_test_pools 2> /dev/null ||
7316                         error "destroy test pools failed"
7317         fi
7318 }
7319 run_test 56wb "check lfs_migrate pool support"
7320
7321 test_56wc() {
7322         local file1="$DIR/$tdir/file1"
7323         local parent_ssize
7324         local parent_scount
7325         local cur_ssize
7326         local cur_scount
7327         local orig_ssize
7328
7329         echo -n "Creating test dir..."
7330         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7331         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7332                 error "cannot set stripe by '-S 1M -c 1'"
7333         echo "done"
7334
7335         echo -n "Setting initial stripe for test file..."
7336         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7337                 error "cannot set stripe"
7338         cur_ssize=$($LFS getstripe -S "$file1")
7339         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7340         echo "done."
7341
7342         # File currently set to -S 512K -c 1
7343
7344         # Ensure -c and -S options are rejected when -R is set
7345         echo -n "Verifying incompatible options are detected..."
7346         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7347                 error "incompatible -c and -R options not detected"
7348         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7349                 error "incompatible -S and -R options not detected"
7350         echo "done."
7351
7352         # Ensure unrecognized options are passed through to 'lfs migrate'
7353         echo -n "Verifying -S option is passed through to lfs migrate..."
7354         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7355                 error "migration failed"
7356         cur_ssize=$($LFS getstripe -S "$file1")
7357         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7358         echo "done."
7359
7360         # File currently set to -S 1M -c 1
7361
7362         # Ensure long options are supported
7363         echo -n "Verifying long options supported..."
7364         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7365                 error "long option without argument not supported"
7366         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7367                 error "long option with argument not supported"
7368         cur_ssize=$($LFS getstripe -S "$file1")
7369         [ $cur_ssize -eq 524288 ] ||
7370                 error "migrate --stripe-size $cur_ssize != 524288"
7371         echo "done."
7372
7373         # File currently set to -S 512K -c 1
7374
7375         if [ "$OSTCOUNT" -gt 1 ]; then
7376                 echo -n "Verifying explicit stripe count can be set..."
7377                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7378                         error "migrate failed"
7379                 cur_scount=$($LFS getstripe -c "$file1")
7380                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7381                 echo "done."
7382         fi
7383
7384         # File currently set to -S 512K -c 1 or -S 512K -c 2
7385
7386         # Ensure parent striping is used if -R is set, and no stripe
7387         # count or size is specified
7388         echo -n "Setting stripe for parent directory..."
7389         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7390                 error "cannot set stripe '-S 2M -c 1'"
7391         echo "done."
7392
7393         echo -n "Verifying restripe option uses parent stripe settings..."
7394         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7395         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7396         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7397                 error "migrate failed"
7398         cur_ssize=$($LFS getstripe -S "$file1")
7399         [ $cur_ssize -eq $parent_ssize ] ||
7400                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7401         cur_scount=$($LFS getstripe -c "$file1")
7402         [ $cur_scount -eq $parent_scount ] ||
7403                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7404         echo "done."
7405
7406         # File currently set to -S 1M -c 1
7407
7408         # Ensure striping is preserved if -R is not set, and no stripe
7409         # count or size is specified
7410         echo -n "Verifying striping size preserved when not specified..."
7411         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7412         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7413                 error "cannot set stripe on parent directory"
7414         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7415                 error "migrate failed"
7416         cur_ssize=$($LFS getstripe -S "$file1")
7417         [ $cur_ssize -eq $orig_ssize ] ||
7418                 error "migrate by default $cur_ssize != $orig_ssize"
7419         echo "done."
7420
7421         # Ensure file name properly detected when final option has no argument
7422         echo -n "Verifying file name properly detected..."
7423         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7424                 error "file name interpreted as option argument"
7425         echo "done."
7426
7427         # Clean up
7428         rm -f "$file1"
7429 }
7430 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7431
7432 test_56wd() {
7433         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7434
7435         local file1=$DIR/$tdir/file1
7436
7437         echo -n "Creating test dir..."
7438         test_mkdir $DIR/$tdir || error "cannot create dir"
7439         echo "done."
7440
7441         echo -n "Creating test file..."
7442         touch $file1
7443         echo "done."
7444
7445         # Ensure 'lfs migrate' will fail by using a non-existent option,
7446         # and make sure rsync is not called to recover
7447         echo -n "Make sure --no-rsync option works..."
7448         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7449                 grep -q 'refusing to fall back to rsync' ||
7450                 error "rsync was called with --no-rsync set"
7451         echo "done."
7452
7453         # Ensure rsync is called without trying 'lfs migrate' first
7454         echo -n "Make sure --rsync option works..."
7455         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7456                 grep -q 'falling back to rsync' &&
7457                 error "lfs migrate was called with --rsync set"
7458         echo "done."
7459
7460         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7461         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7462                 grep -q 'at the same time' ||
7463                 error "--rsync and --no-rsync accepted concurrently"
7464         echo "done."
7465
7466         # Clean up
7467         rm -f $file1
7468 }
7469 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7470
7471 test_56we() {
7472         local td=$DIR/$tdir
7473         local tf=$td/$tfile
7474
7475         test_mkdir $td || error "cannot create $td"
7476         touch $tf || error "cannot touch $tf"
7477
7478         echo -n "Make sure --non-direct|-D works..."
7479         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7480                 grep -q "lfs migrate --non-direct" ||
7481                 error "--non-direct option cannot work correctly"
7482         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7483                 grep -q "lfs migrate -D" ||
7484                 error "-D option cannot work correctly"
7485         echo "done."
7486 }
7487 run_test 56we "check lfs_migrate --non-direct|-D support"
7488
7489 test_56x() {
7490         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7491         check_swap_layouts_support
7492
7493         local dir=$DIR/$tdir
7494         local ref1=/etc/passwd
7495         local file1=$dir/file1
7496
7497         test_mkdir $dir || error "creating dir $dir"
7498         $LFS setstripe -c 2 $file1
7499         cp $ref1 $file1
7500         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7501         stripe=$($LFS getstripe -c $file1)
7502         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7503         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7504
7505         # clean up
7506         rm -f $file1
7507 }
7508 run_test 56x "lfs migration support"
7509
7510 test_56xa() {
7511         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7512         check_swap_layouts_support
7513
7514         local dir=$DIR/$tdir/$testnum
7515
7516         test_mkdir -p $dir
7517
7518         local ref1=/etc/passwd
7519         local file1=$dir/file1
7520
7521         $LFS setstripe -c 2 $file1
7522         cp $ref1 $file1
7523         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7524
7525         local stripe=$($LFS getstripe -c $file1)
7526
7527         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7528         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7529
7530         # clean up
7531         rm -f $file1
7532 }
7533 run_test 56xa "lfs migration --block support"
7534
7535 check_migrate_links() {
7536         local dir="$1"
7537         local file1="$dir/file1"
7538         local begin="$2"
7539         local count="$3"
7540         local runas="$4"
7541         local total_count=$(($begin + $count - 1))
7542         local symlink_count=10
7543         local uniq_count=10
7544
7545         if [ ! -f "$file1" ]; then
7546                 echo -n "creating initial file..."
7547                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7548                         error "cannot setstripe initial file"
7549                 echo "done"
7550
7551                 echo -n "creating symlinks..."
7552                 for s in $(seq 1 $symlink_count); do
7553                         ln -s "$file1" "$dir/slink$s" ||
7554                                 error "cannot create symlinks"
7555                 done
7556                 echo "done"
7557
7558                 echo -n "creating nonlinked files..."
7559                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7560                         error "cannot create nonlinked files"
7561                 echo "done"
7562         fi
7563
7564         # create hard links
7565         if [ ! -f "$dir/file$total_count" ]; then
7566                 echo -n "creating hard links $begin:$total_count..."
7567                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7568                         /dev/null || error "cannot create hard links"
7569                 echo "done"
7570         fi
7571
7572         echo -n "checking number of hard links listed in xattrs..."
7573         local fid=$($LFS getstripe -F "$file1")
7574         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7575
7576         echo "${#paths[*]}"
7577         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7578                         skip "hard link list has unexpected size, skipping test"
7579         fi
7580         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7581                         error "link names should exceed xattrs size"
7582         fi
7583
7584         echo -n "migrating files..."
7585         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7586         local rc=$?
7587         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7588         echo "done"
7589
7590         # make sure all links have been properly migrated
7591         echo -n "verifying files..."
7592         fid=$($LFS getstripe -F "$file1") ||
7593                 error "cannot get fid for file $file1"
7594         for i in $(seq 2 $total_count); do
7595                 local fid2=$($LFS getstripe -F $dir/file$i)
7596
7597                 [ "$fid2" == "$fid" ] ||
7598                         error "migrated hard link has mismatched FID"
7599         done
7600
7601         # make sure hard links were properly detected, and migration was
7602         # performed only once for the entire link set; nonlinked files should
7603         # also be migrated
7604         local actual=$(grep -c 'done' <<< "$migrate_out")
7605         local expected=$(($uniq_count + 1))
7606
7607         [ "$actual" -eq  "$expected" ] ||
7608                 error "hard links individually migrated ($actual != $expected)"
7609
7610         # make sure the correct number of hard links are present
7611         local hardlinks=$(stat -c '%h' "$file1")
7612
7613         [ $hardlinks -eq $total_count ] ||
7614                 error "num hard links $hardlinks != $total_count"
7615         echo "done"
7616
7617         return 0
7618 }
7619
7620 test_56xb() {
7621         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7622                 skip "Need MDS version at least 2.10.55"
7623
7624         local dir="$DIR/$tdir"
7625
7626         test_mkdir "$dir" || error "cannot create dir $dir"
7627
7628         echo "testing lfs migrate mode when all links fit within xattrs"
7629         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7630
7631         echo "testing rsync mode when all links fit within xattrs"
7632         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7633
7634         echo "testing lfs migrate mode when all links do not fit within xattrs"
7635         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7636
7637         echo "testing rsync mode when all links do not fit within xattrs"
7638         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7639
7640         chown -R $RUNAS_ID $dir
7641         echo "testing non-root lfs migrate mode when not all links are in xattr"
7642         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7643
7644         # clean up
7645         rm -rf $dir
7646 }
7647 run_test 56xb "lfs migration hard link support"
7648
7649 test_56xc() {
7650         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7651
7652         local dir="$DIR/$tdir"
7653
7654         test_mkdir "$dir" || error "cannot create dir $dir"
7655
7656         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7657         echo -n "Setting initial stripe for 20MB test file..."
7658         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7659                 error "cannot setstripe 20MB file"
7660         echo "done"
7661         echo -n "Sizing 20MB test file..."
7662         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7663         echo "done"
7664         echo -n "Verifying small file autostripe count is 1..."
7665         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7666                 error "cannot migrate 20MB file"
7667         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7668                 error "cannot get stripe for $dir/20mb"
7669         [ $stripe_count -eq 1 ] ||
7670                 error "unexpected stripe count $stripe_count for 20MB file"
7671         rm -f "$dir/20mb"
7672         echo "done"
7673
7674         # Test 2: File is small enough to fit within the available space on
7675         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7676         # have at least an additional 1KB for each desired stripe for test 3
7677         echo -n "Setting stripe for 1GB test file..."
7678         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7679         echo "done"
7680         echo -n "Sizing 1GB test file..."
7681         # File size is 1GB + 3KB
7682         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7683         echo "done"
7684
7685         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7686         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7687         if (( avail > 524288 * OSTCOUNT )); then
7688                 echo -n "Migrating 1GB file..."
7689                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7690                         error "cannot migrate 1GB file"
7691                 echo "done"
7692                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7693                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7694                         error "cannot getstripe for 1GB file"
7695                 [ $stripe_count -eq 2 ] ||
7696                         error "unexpected stripe count $stripe_count != 2"
7697                 echo "done"
7698         fi
7699
7700         # Test 3: File is too large to fit within the available space on
7701         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7702         if [ $OSTCOUNT -ge 3 ]; then
7703                 # The required available space is calculated as
7704                 # file size (1GB + 3KB) / OST count (3).
7705                 local kb_per_ost=349526
7706
7707                 echo -n "Migrating 1GB file with limit..."
7708                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7709                         error "cannot migrate 1GB file with limit"
7710                 echo "done"
7711
7712                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7713                 echo -n "Verifying 1GB autostripe count with limited space..."
7714                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7715                         error "unexpected stripe count $stripe_count (min 3)"
7716                 echo "done"
7717         fi
7718
7719         # clean up
7720         rm -rf $dir
7721 }
7722 run_test 56xc "lfs migration autostripe"
7723
7724 test_56xd() {
7725         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7726
7727         local dir=$DIR/$tdir
7728         local f_mgrt=$dir/$tfile.mgrt
7729         local f_yaml=$dir/$tfile.yaml
7730         local f_copy=$dir/$tfile.copy
7731         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7732         local layout_copy="-c 2 -S 2M -i 1"
7733         local yamlfile=$dir/yamlfile
7734         local layout_before;
7735         local layout_after;
7736
7737         test_mkdir "$dir" || error "cannot create dir $dir"
7738         $LFS setstripe $layout_yaml $f_yaml ||
7739                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7740         $LFS getstripe --yaml $f_yaml > $yamlfile
7741         $LFS setstripe $layout_copy $f_copy ||
7742                 error "cannot setstripe $f_copy with layout $layout_copy"
7743         touch $f_mgrt
7744         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7745
7746         # 1. test option --yaml
7747         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7748                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7749         layout_before=$(get_layout_param $f_yaml)
7750         layout_after=$(get_layout_param $f_mgrt)
7751         [ "$layout_after" == "$layout_before" ] ||
7752                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7753
7754         # 2. test option --copy
7755         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7756                 error "cannot migrate $f_mgrt with --copy $f_copy"
7757         layout_before=$(get_layout_param $f_copy)
7758         layout_after=$(get_layout_param $f_mgrt)
7759         [ "$layout_after" == "$layout_before" ] ||
7760                 error "lfs_migrate --copy: $layout_after != $layout_before"
7761 }
7762 run_test 56xd "check lfs_migrate --yaml and --copy support"
7763
7764 test_56xe() {
7765         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7766
7767         local dir=$DIR/$tdir
7768         local f_comp=$dir/$tfile
7769         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7770         local layout_before=""
7771         local layout_after=""
7772
7773         test_mkdir "$dir" || error "cannot create dir $dir"
7774         $LFS setstripe $layout $f_comp ||
7775                 error "cannot setstripe $f_comp with layout $layout"
7776         layout_before=$(get_layout_param $f_comp)
7777         dd if=/dev/zero of=$f_comp bs=1M count=4
7778
7779         # 1. migrate a comp layout file by lfs_migrate
7780         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7781         layout_after=$(get_layout_param $f_comp)
7782         [ "$layout_before" == "$layout_after" ] ||
7783                 error "lfs_migrate: $layout_before != $layout_after"
7784
7785         # 2. migrate a comp layout file by lfs migrate
7786         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7787         layout_after=$(get_layout_param $f_comp)
7788         [ "$layout_before" == "$layout_after" ] ||
7789                 error "lfs migrate: $layout_before != $layout_after"
7790 }
7791 run_test 56xe "migrate a composite layout file"
7792
7793 test_56xf() {
7794         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7795
7796         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7797                 skip "Need server version at least 2.13.53"
7798
7799         local dir=$DIR/$tdir
7800         local f_comp=$dir/$tfile
7801         local layout="-E 1M -c1 -E -1 -c2"
7802         local fid_before=""
7803         local fid_after=""
7804
7805         test_mkdir "$dir" || error "cannot create dir $dir"
7806         $LFS setstripe $layout $f_comp ||
7807                 error "cannot setstripe $f_comp with layout $layout"
7808         fid_before=$($LFS getstripe --fid $f_comp)
7809         dd if=/dev/zero of=$f_comp bs=1M count=4
7810
7811         # 1. migrate a comp layout file to a comp layout
7812         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7813         fid_after=$($LFS getstripe --fid $f_comp)
7814         [ "$fid_before" == "$fid_after" ] ||
7815                 error "comp-to-comp migrate: $fid_before != $fid_after"
7816
7817         # 2. migrate a comp layout file to a plain layout
7818         $LFS migrate -c2 $f_comp ||
7819                 error "cannot migrate $f_comp by lfs migrate"
7820         fid_after=$($LFS getstripe --fid $f_comp)
7821         [ "$fid_before" == "$fid_after" ] ||
7822                 error "comp-to-plain migrate: $fid_before != $fid_after"
7823
7824         # 3. migrate a plain layout file to a comp layout
7825         $LFS migrate $layout $f_comp ||
7826                 error "cannot migrate $f_comp by lfs migrate"
7827         fid_after=$($LFS getstripe --fid $f_comp)
7828         [ "$fid_before" == "$fid_after" ] ||
7829                 error "plain-to-comp migrate: $fid_before != $fid_after"
7830 }
7831 run_test 56xf "FID is not lost during migration of a composite layout file"
7832
7833 check_file_ost_range() {
7834         local file="$1"
7835         shift
7836         local range="$*"
7837         local -a file_range
7838         local idx
7839
7840         file_range=($($LFS getstripe -y "$file" |
7841                 awk '/l_ost_idx:/ { print $NF }'))
7842
7843         if [[ "${#file_range[@]}" = 0 ]]; then
7844                 echo "No osts found for $file"
7845                 return 1
7846         fi
7847
7848         for idx in "${file_range[@]}"; do
7849                 [[ " $range " =~ " $idx " ]] ||
7850                         return 1
7851         done
7852
7853         return 0
7854 }
7855
7856 sub_test_56xg() {
7857         local stripe_opt="$1"
7858         local pool="$2"
7859         shift 2
7860         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7861
7862         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7863                 error "Fail to migrate $tfile on $pool"
7864         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7865                 error "$tfile is not in pool $pool"
7866         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7867                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7868 }
7869
7870 test_56xg() {
7871         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7872         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7873         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7874                 skip "Need MDS version newer than 2.14.52"
7875
7876         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7877         local -a pool_ranges=("0 0" "1 1" "0 1")
7878
7879         # init pools
7880         for i in "${!pool_names[@]}"; do
7881                 pool_add ${pool_names[$i]} ||
7882                         error "pool_add failed (pool: ${pool_names[$i]})"
7883                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7884                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7885         done
7886
7887         # init the file to migrate
7888         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7889                 error "Unable to create $tfile on OST1"
7890         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7891                 error "Unable to write on $tfile"
7892
7893         echo "1. migrate $tfile on pool ${pool_names[0]}"
7894         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7895
7896         echo "2. migrate $tfile on pool ${pool_names[2]}"
7897         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7898
7899         echo "3. migrate $tfile on pool ${pool_names[1]}"
7900         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7901
7902         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7903         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7904         echo
7905
7906         # Clean pools
7907         destroy_test_pools ||
7908                 error "pool_destroy failed"
7909 }
7910 run_test 56xg "lfs migrate pool support"
7911
7912 test_56y() {
7913         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7914                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7915
7916         local res=""
7917         local dir=$DIR/$tdir
7918         local f1=$dir/file1
7919         local f2=$dir/file2
7920
7921         test_mkdir -p $dir || error "creating dir $dir"
7922         touch $f1 || error "creating std file $f1"
7923         $MULTIOP $f2 H2c || error "creating released file $f2"
7924
7925         # a directory can be raid0, so ask only for files
7926         res=$($LFS find $dir -L raid0 -type f | wc -l)
7927         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7928
7929         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7930         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7931
7932         # only files can be released, so no need to force file search
7933         res=$($LFS find $dir -L released)
7934         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7935
7936         res=$($LFS find $dir -type f \! -L released)
7937         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7938 }
7939 run_test 56y "lfs find -L raid0|released"
7940
7941 test_56z() { # LU-4824
7942         # This checks to make sure 'lfs find' continues after errors
7943         # There are two classes of errors that should be caught:
7944         # - If multiple paths are provided, all should be searched even if one
7945         #   errors out
7946         # - If errors are encountered during the search, it should not terminate
7947         #   early
7948         local dir=$DIR/$tdir
7949         local i
7950
7951         test_mkdir $dir
7952         for i in d{0..9}; do
7953                 test_mkdir $dir/$i
7954                 touch $dir/$i/$tfile
7955         done
7956         $LFS find $DIR/non_existent_dir $dir &&
7957                 error "$LFS find did not return an error"
7958         # Make a directory unsearchable. This should NOT be the last entry in
7959         # directory order.  Arbitrarily pick the 6th entry
7960         chmod 700 $($LFS find $dir -type d | sed '6!d')
7961
7962         $RUNAS $LFS find $DIR/non_existent $dir
7963         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7964
7965         # The user should be able to see 10 directories and 9 files
7966         (( count == 19 )) ||
7967                 error "$LFS find found $count != 19 entries after error"
7968 }
7969 run_test 56z "lfs find should continue after an error"
7970
7971 test_56aa() { # LU-5937
7972         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7973
7974         local dir=$DIR/$tdir
7975
7976         mkdir $dir
7977         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7978
7979         createmany -o $dir/striped_dir/${tfile}- 1024
7980         local dirs=$($LFS find --size +8k $dir/)
7981
7982         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7983 }
7984 run_test 56aa "lfs find --size under striped dir"
7985
7986 test_56ab() { # LU-10705
7987         test_mkdir $DIR/$tdir
7988         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7989         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7990         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7991         # Flush writes to ensure valid blocks.  Need to be more thorough for
7992         # ZFS, since blocks are not allocated/returned to client immediately.
7993         sync_all_data
7994         wait_zfs_commit ost1 2
7995         cancel_lru_locks osc
7996         ls -ls $DIR/$tdir
7997
7998         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7999
8000         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8001
8002         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8003         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8004
8005         rm -f $DIR/$tdir/$tfile.[123]
8006 }
8007 run_test 56ab "lfs find --blocks"
8008
8009 # LU-11188
8010 test_56aca() {
8011         local dir="$DIR/$tdir"
8012         local perms=(001 002 003 004 005 006 007
8013                      010 020 030 040 050 060 070
8014                      100 200 300 400 500 600 700
8015                      111 222 333 444 555 666 777)
8016         local perm_minus=(8 8 4 8 4 4 2
8017                           8 8 4 8 4 4 2
8018                           8 8 4 8 4 4 2
8019                           4 4 2 4 2 2 1)
8020         local perm_slash=(8  8 12  8 12 12 14
8021                           8  8 12  8 12 12 14
8022                           8  8 12  8 12 12 14
8023                          16 16 24 16 24 24 28)
8024
8025         test_mkdir "$dir"
8026         for perm in ${perms[*]}; do
8027                 touch "$dir/$tfile.$perm"
8028                 chmod $perm "$dir/$tfile.$perm"
8029         done
8030
8031         for ((i = 0; i < ${#perms[*]}; i++)); do
8032                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8033                 (( $num == 1 )) ||
8034                         error "lfs find -perm ${perms[i]}:"\
8035                               "$num != 1"
8036
8037                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8038                 (( $num == ${perm_minus[i]} )) ||
8039                         error "lfs find -perm -${perms[i]}:"\
8040                               "$num != ${perm_minus[i]}"
8041
8042                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8043                 (( $num == ${perm_slash[i]} )) ||
8044                         error "lfs find -perm /${perms[i]}:"\
8045                               "$num != ${perm_slash[i]}"
8046         done
8047 }
8048 run_test 56aca "check lfs find -perm with octal representation"
8049
8050 test_56acb() {
8051         local dir=$DIR/$tdir
8052         # p is the permission of write and execute for user, group and other
8053         # without the umask. It is used to test +wx.
8054         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8055         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8056         local symbolic=(+t  a+t u+t g+t o+t
8057                         g+s u+s o+s +s o+sr
8058                         o=r,ug+o,u+w
8059                         u+ g+ o+ a+ ugo+
8060                         u- g- o- a- ugo-
8061                         u= g= o= a= ugo=
8062                         o=r,ug+o,u+w u=r,a+u,u+w
8063                         g=r,ugo=g,u+w u+x,+X +X
8064                         u+x,u+X u+X u+x,g+X o+r,+X
8065                         u+x,go+X +wx +rwx)
8066
8067         test_mkdir $dir
8068         for perm in ${perms[*]}; do
8069                 touch "$dir/$tfile.$perm"
8070                 chmod $perm "$dir/$tfile.$perm"
8071         done
8072
8073         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8074                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8075
8076                 (( $num == 1 )) ||
8077                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8078         done
8079 }
8080 run_test 56acb "check lfs find -perm with symbolic representation"
8081
8082 test_56acc() {
8083         local dir=$DIR/$tdir
8084         local tests="17777 787 789 abcd
8085                 ug=uu ug=a ug=gu uo=ou urw
8086                 u+xg+x a=r,u+x,"
8087
8088         test_mkdir $dir
8089         for err in $tests; do
8090                 if $LFS find $dir -perm $err 2>/dev/null; then
8091                         error "lfs find -perm $err: parsing should have failed"
8092                 fi
8093         done
8094 }
8095 run_test 56acc "check parsing error for lfs find -perm"
8096
8097 test_56ba() {
8098         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8099                 skip "Need MDS version at least 2.10.50"
8100
8101         # Create composite files with one component
8102         local dir=$DIR/$tdir
8103
8104         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8105         # Create composite files with three components
8106         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8107         # Create non-composite files
8108         createmany -o $dir/${tfile}- 10
8109
8110         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8111
8112         [[ $nfiles == 10 ]] ||
8113                 error "lfs find -E 1M found $nfiles != 10 files"
8114
8115         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8116         [[ $nfiles == 25 ]] ||
8117                 error "lfs find ! -E 1M found $nfiles != 25 files"
8118
8119         # All files have a component that starts at 0
8120         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8121         [[ $nfiles == 35 ]] ||
8122                 error "lfs find --component-start 0 - $nfiles != 35 files"
8123
8124         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8125         [[ $nfiles == 15 ]] ||
8126                 error "lfs find --component-start 2M - $nfiles != 15 files"
8127
8128         # All files created here have a componenet that does not starts at 2M
8129         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8130         [[ $nfiles == 35 ]] ||
8131                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8132
8133         # Find files with a specified number of components
8134         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8135         [[ $nfiles == 15 ]] ||
8136                 error "lfs find --component-count 3 - $nfiles != 15 files"
8137
8138         # Remember non-composite files have a component count of zero
8139         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8140         [[ $nfiles == 10 ]] ||
8141                 error "lfs find --component-count 0 - $nfiles != 10 files"
8142
8143         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8144         [[ $nfiles == 20 ]] ||
8145                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8146
8147         # All files have a flag called "init"
8148         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8149         [[ $nfiles == 35 ]] ||
8150                 error "lfs find --component-flags init - $nfiles != 35 files"
8151
8152         # Multi-component files will have a component not initialized
8153         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8154         [[ $nfiles == 15 ]] ||
8155                 error "lfs find !--component-flags init - $nfiles != 15 files"
8156
8157         rm -rf $dir
8158
8159 }
8160 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8161
8162 test_56ca() {
8163         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8164                 skip "Need MDS version at least 2.10.57"
8165
8166         local td=$DIR/$tdir
8167         local tf=$td/$tfile
8168         local dir
8169         local nfiles
8170         local cmd
8171         local i
8172         local j
8173
8174         # create mirrored directories and mirrored files
8175         mkdir $td || error "mkdir $td failed"
8176         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8177         createmany -o $tf- 10 || error "create $tf- failed"
8178
8179         for i in $(seq 2); do
8180                 dir=$td/dir$i
8181                 mkdir $dir || error "mkdir $dir failed"
8182                 $LFS mirror create -N$((3 + i)) $dir ||
8183                         error "create mirrored dir $dir failed"
8184                 createmany -o $dir/$tfile- 10 ||
8185                         error "create $dir/$tfile- failed"
8186         done
8187
8188         # change the states of some mirrored files
8189         echo foo > $tf-6
8190         for i in $(seq 2); do
8191                 dir=$td/dir$i
8192                 for j in $(seq 4 9); do
8193                         echo foo > $dir/$tfile-$j
8194                 done
8195         done
8196
8197         # find mirrored files with specific mirror count
8198         cmd="$LFS find --mirror-count 3 --type f $td"
8199         nfiles=$($cmd | wc -l)
8200         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8201
8202         cmd="$LFS find ! --mirror-count 3 --type f $td"
8203         nfiles=$($cmd | wc -l)
8204         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8205
8206         cmd="$LFS find --mirror-count +2 --type f $td"
8207         nfiles=$($cmd | wc -l)
8208         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8209
8210         cmd="$LFS find --mirror-count -6 --type f $td"
8211         nfiles=$($cmd | wc -l)
8212         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8213
8214         # find mirrored files with specific file state
8215         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8216         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8217
8218         cmd="$LFS find --mirror-state=ro --type f $td"
8219         nfiles=$($cmd | wc -l)
8220         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8221
8222         cmd="$LFS find ! --mirror-state=ro --type f $td"
8223         nfiles=$($cmd | wc -l)
8224         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8225
8226         cmd="$LFS find --mirror-state=wp --type f $td"
8227         nfiles=$($cmd | wc -l)
8228         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8229
8230         cmd="$LFS find ! --mirror-state=sp --type f $td"
8231         nfiles=$($cmd | wc -l)
8232         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8233 }
8234 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8235
8236 test_56da() { # LU-14179
8237         local path=$DIR/$tdir
8238
8239         test_mkdir $path
8240         cd $path
8241
8242         local longdir=$(str_repeat 'a' 255)
8243
8244         for i in {1..15}; do
8245                 path=$path/$longdir
8246                 test_mkdir $longdir
8247                 cd $longdir
8248         done
8249
8250         local len=${#path}
8251         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8252
8253         test_mkdir $lastdir
8254         cd $lastdir
8255         # PATH_MAX-1
8256         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8257
8258         # NAME_MAX
8259         touch $(str_repeat 'f' 255)
8260
8261         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8262                 error "lfs find reported an error"
8263
8264         rm -rf $DIR/$tdir
8265 }
8266 run_test 56da "test lfs find with long paths"
8267
8268 test_56ea() { #LU-10378
8269         local path=$DIR/$tdir
8270         local pool=$TESTNAME
8271
8272         # Create ost pool
8273         pool_add $pool || error "pool_add $pool failed"
8274         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8275                 error "adding targets to $pool failed"
8276
8277         # Set default pool on directory before creating file
8278         mkdir $path || error "mkdir $path failed"
8279         $LFS setstripe -p $pool $path ||
8280                 error "set OST pool on $pool failed"
8281         touch $path/$tfile || error "touch $path/$tfile failed"
8282
8283         # Compare basic file attributes from -printf and stat
8284         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8285         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8286
8287         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8288                 error "Attrs from lfs find and stat don't match"
8289
8290         # Compare Lustre attributes from lfs find and lfs getstripe
8291         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8292         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8293         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8294         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8295         local fpool=$($LFS getstripe --pool $path/$tfile)
8296         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8297
8298         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8299                 error "Attrs from lfs find and lfs getstripe don't match"
8300
8301         # Verify behavior for unknown escape/format sequences
8302         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8303
8304         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8305                 error "Escape/format codes don't match"
8306 }
8307 run_test 56ea "test lfs find -printf option"
8308
8309 test_57a() {
8310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8311         # note test will not do anything if MDS is not local
8312         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8313                 skip_env "ldiskfs only test"
8314         fi
8315         remote_mds_nodsh && skip "remote MDS with nodsh"
8316
8317         local MNTDEV="osd*.*MDT*.mntdev"
8318         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8319         [ -z "$DEV" ] && error "can't access $MNTDEV"
8320         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8321                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8322                         error "can't access $DEV"
8323                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8324                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8325                 rm $TMP/t57a.dump
8326         done
8327 }
8328 run_test 57a "verify MDS filesystem created with large inodes =="
8329
8330 test_57b() {
8331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8332         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8333                 skip_env "ldiskfs only test"
8334         fi
8335         remote_mds_nodsh && skip "remote MDS with nodsh"
8336
8337         local dir=$DIR/$tdir
8338         local filecount=100
8339         local file1=$dir/f1
8340         local fileN=$dir/f$filecount
8341
8342         rm -rf $dir || error "removing $dir"
8343         test_mkdir -c1 $dir
8344         local mdtidx=$($LFS getstripe -m $dir)
8345         local mdtname=MDT$(printf %04x $mdtidx)
8346         local facet=mds$((mdtidx + 1))
8347
8348         echo "mcreating $filecount files"
8349         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8350
8351         # verify that files do not have EAs yet
8352         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8353                 error "$file1 has an EA"
8354         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8355                 error "$fileN has an EA"
8356
8357         sync
8358         sleep 1
8359         df $dir  #make sure we get new statfs data
8360         local mdsfree=$(do_facet $facet \
8361                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8362         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8363         local file
8364
8365         echo "opening files to create objects/EAs"
8366         for file in $(seq -f $dir/f%g 1 $filecount); do
8367                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8368                         error "opening $file"
8369         done
8370
8371         # verify that files have EAs now
8372         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8373         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8374
8375         sleep 1  #make sure we get new statfs data
8376         df $dir
8377         local mdsfree2=$(do_facet $facet \
8378                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8379         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8380
8381         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8382                 if [ "$mdsfree" != "$mdsfree2" ]; then
8383                         error "MDC before $mdcfree != after $mdcfree2"
8384                 else
8385                         echo "MDC before $mdcfree != after $mdcfree2"
8386                         echo "unable to confirm if MDS has large inodes"
8387                 fi
8388         fi
8389         rm -rf $dir
8390 }
8391 run_test 57b "default LOV EAs are stored inside large inodes ==="
8392
8393 test_58() {
8394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8395         [ -z "$(which wiretest 2>/dev/null)" ] &&
8396                         skip_env "could not find wiretest"
8397
8398         wiretest
8399 }
8400 run_test 58 "verify cross-platform wire constants =============="
8401
8402 test_59() {
8403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8404
8405         echo "touch 130 files"
8406         createmany -o $DIR/f59- 130
8407         echo "rm 130 files"
8408         unlinkmany $DIR/f59- 130
8409         sync
8410         # wait for commitment of removal
8411         wait_delete_completed
8412 }
8413 run_test 59 "verify cancellation of llog records async ========="
8414
8415 TEST60_HEAD="test_60 run $RANDOM"
8416 test_60a() {
8417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8418         remote_mgs_nodsh && skip "remote MGS with nodsh"
8419         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8420                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8421                         skip_env "missing subtest run-llog.sh"
8422
8423         log "$TEST60_HEAD - from kernel mode"
8424         do_facet mgs "$LCTL dk > /dev/null"
8425         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8426         do_facet mgs $LCTL dk > $TMP/$tfile
8427
8428         # LU-6388: test llog_reader
8429         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8430         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8431         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8432                         skip_env "missing llog_reader"
8433         local fstype=$(facet_fstype mgs)
8434         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8435                 skip_env "Only for ldiskfs or zfs type mgs"
8436
8437         local mntpt=$(facet_mntpt mgs)
8438         local mgsdev=$(mgsdevname 1)
8439         local fid_list
8440         local fid
8441         local rec_list
8442         local rec
8443         local rec_type
8444         local obj_file
8445         local path
8446         local seq
8447         local oid
8448         local pass=true
8449
8450         #get fid and record list
8451         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8452                 tail -n 4))
8453         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8454                 tail -n 4))
8455         #remount mgs as ldiskfs or zfs type
8456         stop mgs || error "stop mgs failed"
8457         mount_fstype mgs || error "remount mgs failed"
8458         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8459                 fid=${fid_list[i]}
8460                 rec=${rec_list[i]}
8461                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8462                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8463                 oid=$((16#$oid))
8464
8465                 case $fstype in
8466                         ldiskfs )
8467                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8468                         zfs )
8469                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8470                 esac
8471                 echo "obj_file is $obj_file"
8472                 do_facet mgs $llog_reader $obj_file
8473
8474                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8475                         awk '{ print $3 }' | sed -e "s/^type=//g")
8476                 if [ $rec_type != $rec ]; then
8477                         echo "FAILED test_60a wrong record type $rec_type," \
8478                               "should be $rec"
8479                         pass=false
8480                         break
8481                 fi
8482
8483                 #check obj path if record type is LLOG_LOGID_MAGIC
8484                 if [ "$rec" == "1064553b" ]; then
8485                         path=$(do_facet mgs $llog_reader $obj_file |
8486                                 grep "path=" | awk '{ print $NF }' |
8487                                 sed -e "s/^path=//g")
8488                         if [ $obj_file != $mntpt/$path ]; then
8489                                 echo "FAILED test_60a wrong obj path" \
8490                                       "$montpt/$path, should be $obj_file"
8491                                 pass=false
8492                                 break
8493                         fi
8494                 fi
8495         done
8496         rm -f $TMP/$tfile
8497         #restart mgs before "error", otherwise it will block the next test
8498         stop mgs || error "stop mgs failed"
8499         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8500         $pass || error "test failed, see FAILED test_60a messages for specifics"
8501 }
8502 run_test 60a "llog_test run from kernel module and test llog_reader"
8503
8504 test_60b() { # bug 6411
8505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8506
8507         dmesg > $DIR/$tfile
8508         LLOG_COUNT=$(do_facet mgs dmesg |
8509                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8510                           /llog_[a-z]*.c:[0-9]/ {
8511                                 if (marker)
8512                                         from_marker++
8513                                 from_begin++
8514                           }
8515                           END {
8516                                 if (marker)
8517                                         print from_marker
8518                                 else
8519                                         print from_begin
8520                           }")
8521
8522         [[ $LLOG_COUNT -gt 120 ]] &&
8523                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8524 }
8525 run_test 60b "limit repeated messages from CERROR/CWARN"
8526
8527 test_60c() {
8528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8529
8530         echo "create 5000 files"
8531         createmany -o $DIR/f60c- 5000
8532 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8533         lctl set_param fail_loc=0x80000137
8534         unlinkmany $DIR/f60c- 5000
8535         lctl set_param fail_loc=0
8536 }
8537 run_test 60c "unlink file when mds full"
8538
8539 test_60d() {
8540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8541
8542         SAVEPRINTK=$(lctl get_param -n printk)
8543         # verify "lctl mark" is even working"
8544         MESSAGE="test message ID $RANDOM $$"
8545         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8546         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8547
8548         lctl set_param printk=0 || error "set lnet.printk failed"
8549         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8550         MESSAGE="new test message ID $RANDOM $$"
8551         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8552         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8553         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8554
8555         lctl set_param -n printk="$SAVEPRINTK"
8556 }
8557 run_test 60d "test printk console message masking"
8558
8559 test_60e() {
8560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8561         remote_mds_nodsh && skip "remote MDS with nodsh"
8562
8563         touch $DIR/$tfile
8564 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8565         do_facet mds1 lctl set_param fail_loc=0x15b
8566         rm $DIR/$tfile
8567 }
8568 run_test 60e "no space while new llog is being created"
8569
8570 test_60f() {
8571         local old_path=$($LCTL get_param -n debug_path)
8572
8573         stack_trap "$LCTL set_param debug_path=$old_path"
8574         stack_trap "rm -f $TMP/$tfile*"
8575         rm -f $TMP/$tfile* 2> /dev/null
8576         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8577         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8578         test_mkdir $DIR/$tdir
8579         # retry in case the open is cached and not released
8580         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8581                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8582                 sleep 0.1
8583         done
8584         ls $TMP/$tfile*
8585         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8586 }
8587 run_test 60f "change debug_path works"
8588
8589 test_60g() {
8590         local pid
8591         local i
8592
8593         test_mkdir -c $MDSCOUNT $DIR/$tdir
8594
8595         (
8596                 local index=0
8597                 while true; do
8598                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8599                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8600                                 2>/dev/null
8601                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8602                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8603                         index=$((index + 1))
8604                 done
8605         ) &
8606
8607         pid=$!
8608
8609         for i in {0..100}; do
8610                 # define OBD_FAIL_OSD_TXN_START    0x19a
8611                 local index=$((i % MDSCOUNT + 1))
8612
8613                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8614                         > /dev/null
8615                 sleep 0.01
8616         done
8617
8618         kill -9 $pid
8619
8620         for i in $(seq $MDSCOUNT); do
8621                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8622         done
8623
8624         mkdir $DIR/$tdir/new || error "mkdir failed"
8625         rmdir $DIR/$tdir/new || error "rmdir failed"
8626
8627         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8628                 -t namespace
8629         for i in $(seq $MDSCOUNT); do
8630                 wait_update_facet mds$i "$LCTL get_param -n \
8631                         mdd.$(facet_svc mds$i).lfsck_namespace |
8632                         awk '/^status/ { print \\\$2 }'" "completed"
8633         done
8634
8635         ls -R $DIR/$tdir
8636         rm -rf $DIR/$tdir || error "rmdir failed"
8637 }
8638 run_test 60g "transaction abort won't cause MDT hung"
8639
8640 test_60h() {
8641         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8642                 skip "Need MDS version at least 2.12.52"
8643         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8644
8645         local f
8646
8647         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8648         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8649         for fail_loc in 0x80000188 0x80000189; do
8650                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8651                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8652                         error "mkdir $dir-$fail_loc failed"
8653                 for i in {0..10}; do
8654                         # create may fail on missing stripe
8655                         echo $i > $DIR/$tdir-$fail_loc/$i
8656                 done
8657                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8658                         error "getdirstripe $tdir-$fail_loc failed"
8659                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8660                         error "migrate $tdir-$fail_loc failed"
8661                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8662                         error "getdirstripe $tdir-$fail_loc failed"
8663                 pushd $DIR/$tdir-$fail_loc
8664                 for f in *; do
8665                         echo $f | cmp $f - || error "$f data mismatch"
8666                 done
8667                 popd
8668                 rm -rf $DIR/$tdir-$fail_loc
8669         done
8670 }
8671 run_test 60h "striped directory with missing stripes can be accessed"
8672
8673 function t60i_load() {
8674         mkdir $DIR/$tdir
8675         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8676         $LCTL set_param fail_loc=0x131c fail_val=1
8677         for ((i=0; i<5000; i++)); do
8678                 touch $DIR/$tdir/f$i
8679         done
8680 }
8681
8682 test_60i() {
8683         changelog_register || error "changelog_register failed"
8684         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8685         changelog_users $SINGLEMDS | grep -q $cl_user ||
8686                 error "User $cl_user not found in changelog_users"
8687         changelog_chmask "ALL"
8688         t60i_load &
8689         local PID=$!
8690         for((i=0; i<100; i++)); do
8691                 changelog_dump >/dev/null ||
8692                         error "can't read changelog"
8693         done
8694         kill $PID
8695         wait $PID
8696         changelog_deregister || error "changelog_deregister failed"
8697         $LCTL set_param fail_loc=0
8698 }
8699 run_test 60i "llog: new record vs reader race"
8700
8701 test_61a() {
8702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8703
8704         f="$DIR/f61"
8705         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8706         cancel_lru_locks osc
8707         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8708         sync
8709 }
8710 run_test 61a "mmap() writes don't make sync hang ================"
8711
8712 test_61b() {
8713         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8714 }
8715 run_test 61b "mmap() of unstriped file is successful"
8716
8717 # bug 2330 - insufficient obd_match error checking causes LBUG
8718 test_62() {
8719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8720
8721         f="$DIR/f62"
8722         echo foo > $f
8723         cancel_lru_locks osc
8724         lctl set_param fail_loc=0x405
8725         cat $f && error "cat succeeded, expect -EIO"
8726         lctl set_param fail_loc=0
8727 }
8728 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8729 # match every page all of the time.
8730 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8731
8732 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8733 # Though this test is irrelevant anymore, it helped to reveal some
8734 # other grant bugs (LU-4482), let's keep it.
8735 test_63a() {   # was test_63
8736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8737
8738         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8739
8740         for i in `seq 10` ; do
8741                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8742                 sleep 5
8743                 kill $!
8744                 sleep 1
8745         done
8746
8747         rm -f $DIR/f63 || true
8748 }
8749 run_test 63a "Verify oig_wait interruption does not crash ======="
8750
8751 # bug 2248 - async write errors didn't return to application on sync
8752 # bug 3677 - async write errors left page locked
8753 test_63b() {
8754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8755
8756         debugsave
8757         lctl set_param debug=-1
8758
8759         # ensure we have a grant to do async writes
8760         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8761         rm $DIR/$tfile
8762
8763         sync    # sync lest earlier test intercept the fail_loc
8764
8765         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8766         lctl set_param fail_loc=0x80000406
8767         $MULTIOP $DIR/$tfile Owy && \
8768                 error "sync didn't return ENOMEM"
8769         sync; sleep 2; sync     # do a real sync this time to flush page
8770         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8771                 error "locked page left in cache after async error" || true
8772         debugrestore
8773 }
8774 run_test 63b "async write errors should be returned to fsync ==="
8775
8776 test_64a () {
8777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8778
8779         lfs df $DIR
8780         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8781 }
8782 run_test 64a "verify filter grant calculations (in kernel) ====="
8783
8784 test_64b () {
8785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8786
8787         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8788 }
8789 run_test 64b "check out-of-space detection on client"
8790
8791 test_64c() {
8792         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8793 }
8794 run_test 64c "verify grant shrink"
8795
8796 import_param() {
8797         local tgt=$1
8798         local param=$2
8799
8800         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8801 }
8802
8803 # this does exactly what osc_request.c:osc_announce_cached() does in
8804 # order to calculate max amount of grants to ask from server
8805 want_grant() {
8806         local tgt=$1
8807
8808         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8809         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8810
8811         ((rpc_in_flight++));
8812         nrpages=$((nrpages * rpc_in_flight))
8813
8814         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8815
8816         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8817
8818         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8819         local undirty=$((nrpages * PAGE_SIZE))
8820
8821         local max_extent_pages
8822         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8823         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8824         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8825         local grant_extent_tax
8826         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8827
8828         undirty=$((undirty + nrextents * grant_extent_tax))
8829
8830         echo $undirty
8831 }
8832
8833 # this is size of unit for grant allocation. It should be equal to
8834 # what tgt_grant.c:tgt_grant_chunk() calculates
8835 grant_chunk() {
8836         local tgt=$1
8837         local max_brw_size
8838         local grant_extent_tax
8839
8840         max_brw_size=$(import_param $tgt max_brw_size)
8841
8842         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8843
8844         echo $(((max_brw_size + grant_extent_tax) * 2))
8845 }
8846
8847 test_64d() {
8848         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8849                 skip "OST < 2.10.55 doesn't limit grants enough"
8850
8851         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8852
8853         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8854                 skip "no grant_param connect flag"
8855
8856         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8857
8858         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8859         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8860
8861
8862         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8863         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8864
8865         $LFS setstripe $DIR/$tfile -i 0 -c 1
8866         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8867         ddpid=$!
8868
8869         while kill -0 $ddpid; do
8870                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8871
8872                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8873                         kill $ddpid
8874                         error "cur_grant $cur_grant > $max_cur_granted"
8875                 fi
8876
8877                 sleep 1
8878         done
8879 }
8880 run_test 64d "check grant limit exceed"
8881
8882 check_grants() {
8883         local tgt=$1
8884         local expected=$2
8885         local msg=$3
8886         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8887
8888         ((cur_grants == expected)) ||
8889                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8890 }
8891
8892 round_up_p2() {
8893         echo $((($1 + $2 - 1) & ~($2 - 1)))
8894 }
8895
8896 test_64e() {
8897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8898         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8899                 skip "Need OSS version at least 2.11.56"
8900
8901         # Remount client to reset grant
8902         remount_client $MOUNT || error "failed to remount client"
8903         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8904
8905         local init_grants=$(import_param $osc_tgt initial_grant)
8906
8907         check_grants $osc_tgt $init_grants "init grants"
8908
8909         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8910         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8911         local gbs=$(import_param $osc_tgt grant_block_size)
8912
8913         # write random number of bytes from max_brw_size / 4 to max_brw_size
8914         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8915         # align for direct io
8916         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8917         # round to grant consumption unit
8918         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8919
8920         local grants=$((wb_round_up + extent_tax))
8921
8922         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8923
8924         # define OBD_FAIL_TGT_NO_GRANT 0x725
8925         # make the server not grant more back
8926         do_facet ost1 $LCTL set_param fail_loc=0x725
8927         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8928
8929         do_facet ost1 $LCTL set_param fail_loc=0
8930
8931         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8932
8933         rm -f $DIR/$tfile || error "rm failed"
8934
8935         # Remount client to reset grant
8936         remount_client $MOUNT || error "failed to remount client"
8937         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8938
8939         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8940
8941         # define OBD_FAIL_TGT_NO_GRANT 0x725
8942         # make the server not grant more back
8943         do_facet ost1 $LCTL set_param fail_loc=0x725
8944         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8945         do_facet ost1 $LCTL set_param fail_loc=0
8946
8947         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8948 }
8949 run_test 64e "check grant consumption (no grant allocation)"
8950
8951 test_64f() {
8952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8953
8954         # Remount client to reset grant
8955         remount_client $MOUNT || error "failed to remount client"
8956         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8957
8958         local init_grants=$(import_param $osc_tgt initial_grant)
8959         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8960         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8961         local gbs=$(import_param $osc_tgt grant_block_size)
8962         local chunk=$(grant_chunk $osc_tgt)
8963
8964         # write random number of bytes from max_brw_size / 4 to max_brw_size
8965         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8966         # align for direct io
8967         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8968         # round to grant consumption unit
8969         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8970
8971         local grants=$((wb_round_up + extent_tax))
8972
8973         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8974         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8975                 error "error writing to $DIR/$tfile"
8976
8977         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8978                 "direct io with grant allocation"
8979
8980         rm -f $DIR/$tfile || error "rm failed"
8981
8982         # Remount client to reset grant
8983         remount_client $MOUNT || error "failed to remount client"
8984         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8985
8986         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8987
8988         local cmd="oO_WRONLY:w${write_bytes}_yc"
8989
8990         $MULTIOP $DIR/$tfile $cmd &
8991         MULTIPID=$!
8992         sleep 1
8993
8994         check_grants $osc_tgt $((init_grants - grants)) \
8995                 "buffered io, not write rpc"
8996
8997         kill -USR1 $MULTIPID
8998         wait
8999
9000         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9001                 "buffered io, one RPC"
9002 }
9003 run_test 64f "check grant consumption (with grant allocation)"
9004
9005 test_64g() {
9006         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9007                 skip "Need MDS version at least 2.14.56"
9008
9009         local mdts=$(comma_list $(mdts_nodes))
9010
9011         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9012                         tr '\n' ' ')
9013         stack_trap "$LCTL set_param $old"
9014
9015         # generate dirty pages and increase dirty granted on MDT
9016         stack_trap "rm -f $DIR/$tfile-*"
9017         for (( i = 0; i < 10; i++)); do
9018                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9019                         error "can't set stripe"
9020                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9021                         error "can't dd"
9022                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9023                         $LFS getstripe $DIR/$tfile-$i
9024                         error "not DoM file"
9025                 }
9026         done
9027
9028         # flush dirty pages
9029         sync
9030
9031         # wait until grant shrink reset grant dirty on MDTs
9032         for ((i = 0; i < 120; i++)); do
9033                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9034                         awk '{sum=sum+$1} END {print sum}')
9035                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9036                 echo "$grant_dirty grants, $vm_dirty pages"
9037                 (( grant_dirty + vm_dirty == 0 )) && break
9038                 (( i == 3 )) && sync &&
9039                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9040                 sleep 1
9041         done
9042
9043         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9044                 awk '{sum=sum+$1} END {print sum}')
9045         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9046 }
9047 run_test 64g "grant shrink on MDT"
9048
9049 test_64h() {
9050         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9051                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9052
9053         local instance=$($LFS getname -i $DIR)
9054         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9055         local num_exps=$(do_facet ost1 \
9056             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9057         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9058         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9059         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9060
9061         # 10MiB is for file to be written, max_brw_size * 16 *
9062         # num_exps is space reserve so that tgt_grant_shrink() decided
9063         # to not shrink
9064         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9065         (( avail * 1024 < expect )) &&
9066                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9067
9068         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9069         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9070         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9071         $LCTL set_param osc.*OST0000*.grant_shrink=1
9072         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9073
9074         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9075         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9076
9077         # drop cache so that coming read would do rpc
9078         cancel_lru_locks osc
9079
9080         # shrink interval is set to 10, pause for 7 seconds so that
9081         # grant thread did not wake up yet but coming read entered
9082         # shrink mode for rpc (osc_should_shrink_grant())
9083         sleep 7
9084
9085         declare -a cur_grant_bytes
9086         declare -a tot_granted
9087         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9088         tot_granted[0]=$(do_facet ost1 \
9089             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9090
9091         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9092
9093         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9094         tot_granted[1]=$(do_facet ost1 \
9095             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9096
9097         # grant change should be equal on both sides
9098         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9099                 tot_granted[0] - tot_granted[1])) ||
9100                 error "grant change mismatch, "                                \
9101                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9102                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9103 }
9104 run_test 64h "grant shrink on read"
9105
9106 test_64i() {
9107         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9108                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9109
9110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9111         remote_ost_nodsh && skip "remote OSTs with nodsh"
9112
9113         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9114
9115         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9116
9117         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9118         local instance=$($LFS getname -i $DIR)
9119
9120         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9121         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9122
9123         # shrink grants and simulate rpc loss
9124         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9125         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9126         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9127
9128         fail ost1
9129
9130         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9131
9132         local testid=$(echo $TESTNAME | tr '_' ' ')
9133
9134         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9135                 grep "GRANT, real grant" &&
9136                 error "client has more grants then it owns" || true
9137 }
9138 run_test 64i "shrink on reconnect"
9139
9140 # bug 1414 - set/get directories' stripe info
9141 test_65a() {
9142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9143
9144         test_mkdir $DIR/$tdir
9145         touch $DIR/$tdir/f1
9146         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9147 }
9148 run_test 65a "directory with no stripe info"
9149
9150 test_65b() {
9151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9152
9153         test_mkdir $DIR/$tdir
9154         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9155
9156         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9157                                                 error "setstripe"
9158         touch $DIR/$tdir/f2
9159         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9160 }
9161 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9162
9163 test_65c() {
9164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9165         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9166
9167         test_mkdir $DIR/$tdir
9168         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9169
9170         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9171                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9172         touch $DIR/$tdir/f3
9173         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9174 }
9175 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9176
9177 test_65d() {
9178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9179
9180         test_mkdir $DIR/$tdir
9181         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9182         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9183
9184         if [[ $STRIPECOUNT -le 0 ]]; then
9185                 sc=1
9186         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9187                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9188                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9189         else
9190                 sc=$(($STRIPECOUNT - 1))
9191         fi
9192         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9193         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9194         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9195                 error "lverify failed"
9196 }
9197 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9198
9199 test_65e() {
9200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9201
9202         test_mkdir $DIR/$tdir
9203
9204         $LFS setstripe $DIR/$tdir || error "setstripe"
9205         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9206                                         error "no stripe info failed"
9207         touch $DIR/$tdir/f6
9208         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9209 }
9210 run_test 65e "directory setstripe defaults"
9211
9212 test_65f() {
9213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9214
9215         test_mkdir $DIR/${tdir}f
9216         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9217                 error "setstripe succeeded" || true
9218 }
9219 run_test 65f "dir setstripe permission (should return error) ==="
9220
9221 test_65g() {
9222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9223
9224         test_mkdir $DIR/$tdir
9225         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9226
9227         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9228                 error "setstripe -S failed"
9229         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9230         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9231                 error "delete default stripe failed"
9232 }
9233 run_test 65g "directory setstripe -d"
9234
9235 test_65h() {
9236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9237
9238         test_mkdir $DIR/$tdir
9239         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9240
9241         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9242                 error "setstripe -S failed"
9243         test_mkdir $DIR/$tdir/dd1
9244         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9245                 error "stripe info inherit failed"
9246 }
9247 run_test 65h "directory stripe info inherit ===================="
9248
9249 test_65i() {
9250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9251
9252         save_layout_restore_at_exit $MOUNT
9253
9254         # bug6367: set non-default striping on root directory
9255         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9256
9257         # bug12836: getstripe on -1 default directory striping
9258         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9259
9260         # bug12836: getstripe -v on -1 default directory striping
9261         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9262
9263         # bug12836: new find on -1 default directory striping
9264         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9265 }
9266 run_test 65i "various tests to set root directory striping"
9267
9268 test_65j() { # bug6367
9269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9270
9271         sync; sleep 1
9272
9273         # if we aren't already remounting for each test, do so for this test
9274         if [ "$I_MOUNTED" = "yes" ]; then
9275                 cleanup || error "failed to unmount"
9276                 setup
9277         fi
9278
9279         save_layout_restore_at_exit $MOUNT
9280
9281         $LFS setstripe -d $MOUNT || error "setstripe failed"
9282 }
9283 run_test 65j "set default striping on root directory (bug 6367)="
9284
9285 cleanup_65k() {
9286         rm -rf $DIR/$tdir
9287         wait_delete_completed
9288         do_facet $SINGLEMDS "lctl set_param -n \
9289                 osp.$ost*MDT0000.max_create_count=$max_count"
9290         do_facet $SINGLEMDS "lctl set_param -n \
9291                 osp.$ost*MDT0000.create_count=$count"
9292         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9293         echo $INACTIVE_OSC "is Activate"
9294
9295         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9296 }
9297
9298 test_65k() { # bug11679
9299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9300         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9301         remote_mds_nodsh && skip "remote MDS with nodsh"
9302
9303         local disable_precreate=true
9304         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9305                 disable_precreate=false
9306
9307         echo "Check OST status: "
9308         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9309                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9310
9311         for OSC in $MDS_OSCS; do
9312                 echo $OSC "is active"
9313                 do_facet $SINGLEMDS lctl --device %$OSC activate
9314         done
9315
9316         for INACTIVE_OSC in $MDS_OSCS; do
9317                 local ost=$(osc_to_ost $INACTIVE_OSC)
9318                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9319                                lov.*md*.target_obd |
9320                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9321
9322                 mkdir -p $DIR/$tdir
9323                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9324                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9325
9326                 echo "Deactivate: " $INACTIVE_OSC
9327                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9328
9329                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9330                               osp.$ost*MDT0000.create_count")
9331                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9332                                   osp.$ost*MDT0000.max_create_count")
9333                 $disable_precreate &&
9334                         do_facet $SINGLEMDS "lctl set_param -n \
9335                                 osp.$ost*MDT0000.max_create_count=0"
9336
9337                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9338                         [ -f $DIR/$tdir/$idx ] && continue
9339                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9340                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9341                                 { cleanup_65k;
9342                                   error "setstripe $idx should succeed"; }
9343                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9344                 done
9345                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9346                 rmdir $DIR/$tdir
9347
9348                 do_facet $SINGLEMDS "lctl set_param -n \
9349                         osp.$ost*MDT0000.max_create_count=$max_count"
9350                 do_facet $SINGLEMDS "lctl set_param -n \
9351                         osp.$ost*MDT0000.create_count=$count"
9352                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9353                 echo $INACTIVE_OSC "is Activate"
9354
9355                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9356         done
9357 }
9358 run_test 65k "validate manual striping works properly with deactivated OSCs"
9359
9360 test_65l() { # bug 12836
9361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9362
9363         test_mkdir -p $DIR/$tdir/test_dir
9364         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9365         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9366 }
9367 run_test 65l "lfs find on -1 stripe dir ========================"
9368
9369 test_65m() {
9370         local layout=$(save_layout $MOUNT)
9371         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9372                 restore_layout $MOUNT $layout
9373                 error "setstripe should fail by non-root users"
9374         }
9375         true
9376 }
9377 run_test 65m "normal user can't set filesystem default stripe"
9378
9379 test_65n() {
9380         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9381         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9382                 skip "Need MDS version at least 2.12.50"
9383         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9384
9385         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9386         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9387         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9388
9389         save_layout_restore_at_exit $MOUNT
9390
9391         # new subdirectory under root directory should not inherit
9392         # the default layout from root
9393         local dir1=$MOUNT/$tdir-1
9394         mkdir $dir1 || error "mkdir $dir1 failed"
9395         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9396                 error "$dir1 shouldn't have LOV EA"
9397
9398         # delete the default layout on root directory
9399         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9400
9401         local dir2=$MOUNT/$tdir-2
9402         mkdir $dir2 || error "mkdir $dir2 failed"
9403         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9404                 error "$dir2 shouldn't have LOV EA"
9405
9406         # set a new striping pattern on root directory
9407         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9408         local new_def_stripe_size=$((def_stripe_size * 2))
9409         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9410                 error "set stripe size on $MOUNT failed"
9411
9412         # new file created in $dir2 should inherit the new stripe size from
9413         # the filesystem default
9414         local file2=$dir2/$tfile-2
9415         touch $file2 || error "touch $file2 failed"
9416
9417         local file2_stripe_size=$($LFS getstripe -S $file2)
9418         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9419         {
9420                 echo "file2_stripe_size: '$file2_stripe_size'"
9421                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9422                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9423         }
9424
9425         local dir3=$MOUNT/$tdir-3
9426         mkdir $dir3 || error "mkdir $dir3 failed"
9427         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9428         # the root layout, which is the actual default layout that will be used
9429         # when new files are created in $dir3.
9430         local dir3_layout=$(get_layout_param $dir3)
9431         local root_dir_layout=$(get_layout_param $MOUNT)
9432         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9433         {
9434                 echo "dir3_layout: '$dir3_layout'"
9435                 echo "root_dir_layout: '$root_dir_layout'"
9436                 error "$dir3 should show the default layout from $MOUNT"
9437         }
9438
9439         # set OST pool on root directory
9440         local pool=$TESTNAME
9441         pool_add $pool || error "add $pool failed"
9442         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9443                 error "add targets to $pool failed"
9444
9445         $LFS setstripe -p $pool $MOUNT ||
9446                 error "set OST pool on $MOUNT failed"
9447
9448         # new file created in $dir3 should inherit the pool from
9449         # the filesystem default
9450         local file3=$dir3/$tfile-3
9451         touch $file3 || error "touch $file3 failed"
9452
9453         local file3_pool=$($LFS getstripe -p $file3)
9454         [[ "$file3_pool" = "$pool" ]] ||
9455                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9456
9457         local dir4=$MOUNT/$tdir-4
9458         mkdir $dir4 || error "mkdir $dir4 failed"
9459         local dir4_layout=$(get_layout_param $dir4)
9460         root_dir_layout=$(get_layout_param $MOUNT)
9461         echo "$LFS getstripe -d $dir4"
9462         $LFS getstripe -d $dir4
9463         echo "$LFS getstripe -d $MOUNT"
9464         $LFS getstripe -d $MOUNT
9465         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9466         {
9467                 echo "dir4_layout: '$dir4_layout'"
9468                 echo "root_dir_layout: '$root_dir_layout'"
9469                 error "$dir4 should show the default layout from $MOUNT"
9470         }
9471
9472         # new file created in $dir4 should inherit the pool from
9473         # the filesystem default
9474         local file4=$dir4/$tfile-4
9475         touch $file4 || error "touch $file4 failed"
9476
9477         local file4_pool=$($LFS getstripe -p $file4)
9478         [[ "$file4_pool" = "$pool" ]] ||
9479                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9480
9481         # new subdirectory under non-root directory should inherit
9482         # the default layout from its parent directory
9483         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9484                 error "set directory layout on $dir4 failed"
9485
9486         local dir5=$dir4/$tdir-5
9487         mkdir $dir5 || error "mkdir $dir5 failed"
9488
9489         dir4_layout=$(get_layout_param $dir4)
9490         local dir5_layout=$(get_layout_param $dir5)
9491         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9492         {
9493                 echo "dir4_layout: '$dir4_layout'"
9494                 echo "dir5_layout: '$dir5_layout'"
9495                 error "$dir5 should inherit the default layout from $dir4"
9496         }
9497
9498         # though subdir under ROOT doesn't inherit default layout, but
9499         # its sub dir/file should be created with default layout.
9500         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9501         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9502                 skip "Need MDS version at least 2.12.59"
9503
9504         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9505         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9506         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9507
9508         if [ $default_lmv_hash == "none" ]; then
9509                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9510         else
9511                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9512                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9513         fi
9514
9515         $LFS setdirstripe -D -c 2 $MOUNT ||
9516                 error "setdirstripe -D -c 2 failed"
9517         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9518         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9519         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9520
9521         # $dir4 layout includes pool
9522         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9523         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9524                 error "pool lost on setstripe"
9525         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9526         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9527                 error "pool lost on compound layout setstripe"
9528 }
9529 run_test 65n "don't inherit default layout from root for new subdirectories"
9530
9531 # bug 2543 - update blocks count on client
9532 test_66() {
9533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9534
9535         COUNT=${COUNT:-8}
9536         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9537         sync; sync_all_data; sync; sync_all_data
9538         cancel_lru_locks osc
9539         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9540         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9541 }
9542 run_test 66 "update inode blocks count on client ==============="
9543
9544 meminfo() {
9545         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9546 }
9547
9548 swap_used() {
9549         swapon -s | awk '($1 == "'$1'") { print $4 }'
9550 }
9551
9552 # bug5265, obdfilter oa2dentry return -ENOENT
9553 # #define OBD_FAIL_SRV_ENOENT 0x217
9554 test_69() {
9555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9556         remote_ost_nodsh && skip "remote OST with nodsh"
9557
9558         f="$DIR/$tfile"
9559         $LFS setstripe -c 1 -i 0 $f
9560
9561         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9562
9563         do_facet ost1 lctl set_param fail_loc=0x217
9564         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9565         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9566
9567         do_facet ost1 lctl set_param fail_loc=0
9568         $DIRECTIO write $f 0 2 || error "write error"
9569
9570         cancel_lru_locks osc
9571         $DIRECTIO read $f 0 1 || error "read error"
9572
9573         do_facet ost1 lctl set_param fail_loc=0x217
9574         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9575
9576         do_facet ost1 lctl set_param fail_loc=0
9577         rm -f $f
9578 }
9579 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9580
9581 test_71() {
9582         test_mkdir $DIR/$tdir
9583         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9584         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9585 }
9586 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9587
9588 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9590         [ "$RUNAS_ID" = "$UID" ] &&
9591                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9592         # Check that testing environment is properly set up. Skip if not
9593         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9594                 skip_env "User $RUNAS_ID does not exist - skipping"
9595
9596         touch $DIR/$tfile
9597         chmod 777 $DIR/$tfile
9598         chmod ug+s $DIR/$tfile
9599         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9600                 error "$RUNAS dd $DIR/$tfile failed"
9601         # See if we are still setuid/sgid
9602         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9603                 error "S/gid is not dropped on write"
9604         # Now test that MDS is updated too
9605         cancel_lru_locks mdc
9606         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9607                 error "S/gid is not dropped on MDS"
9608         rm -f $DIR/$tfile
9609 }
9610 run_test 72a "Test that remove suid works properly (bug5695) ===="
9611
9612 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9613         local perm
9614
9615         [ "$RUNAS_ID" = "$UID" ] &&
9616                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9617         [ "$RUNAS_ID" -eq 0 ] &&
9618                 skip_env "RUNAS_ID = 0 -- skipping"
9619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9620         # Check that testing environment is properly set up. Skip if not
9621         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9622                 skip_env "User $RUNAS_ID does not exist - skipping"
9623
9624         touch $DIR/${tfile}-f{g,u}
9625         test_mkdir $DIR/${tfile}-dg
9626         test_mkdir $DIR/${tfile}-du
9627         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9628         chmod g+s $DIR/${tfile}-{f,d}g
9629         chmod u+s $DIR/${tfile}-{f,d}u
9630         for perm in 777 2777 4777; do
9631                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9632                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9633                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9634                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9635         done
9636         true
9637 }
9638 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9639
9640 # bug 3462 - multiple simultaneous MDC requests
9641 test_73() {
9642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9643
9644         test_mkdir $DIR/d73-1
9645         test_mkdir $DIR/d73-2
9646         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9647         pid1=$!
9648
9649         lctl set_param fail_loc=0x80000129
9650         $MULTIOP $DIR/d73-1/f73-2 Oc &
9651         sleep 1
9652         lctl set_param fail_loc=0
9653
9654         $MULTIOP $DIR/d73-2/f73-3 Oc &
9655         pid3=$!
9656
9657         kill -USR1 $pid1
9658         wait $pid1 || return 1
9659
9660         sleep 25
9661
9662         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9663         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9664         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9665
9666         rm -rf $DIR/d73-*
9667 }
9668 run_test 73 "multiple MDC requests (should not deadlock)"
9669
9670 test_74a() { # bug 6149, 6184
9671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9672
9673         touch $DIR/f74a
9674         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9675         #
9676         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9677         # will spin in a tight reconnection loop
9678         $LCTL set_param fail_loc=0x8000030e
9679         # get any lock that won't be difficult - lookup works.
9680         ls $DIR/f74a
9681         $LCTL set_param fail_loc=0
9682         rm -f $DIR/f74a
9683         true
9684 }
9685 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9686
9687 test_74b() { # bug 13310
9688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9689
9690         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9691         #
9692         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9693         # will spin in a tight reconnection loop
9694         $LCTL set_param fail_loc=0x8000030e
9695         # get a "difficult" lock
9696         touch $DIR/f74b
9697         $LCTL set_param fail_loc=0
9698         rm -f $DIR/f74b
9699         true
9700 }
9701 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9702
9703 test_74c() {
9704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9705
9706         #define OBD_FAIL_LDLM_NEW_LOCK
9707         $LCTL set_param fail_loc=0x319
9708         touch $DIR/$tfile && error "touch successful"
9709         $LCTL set_param fail_loc=0
9710         true
9711 }
9712 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9713
9714 slab_lic=/sys/kernel/slab/lustre_inode_cache
9715 num_objects() {
9716         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9717         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9718                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9719 }
9720
9721 test_76a() { # Now for b=20433, added originally in b=1443
9722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9723
9724         cancel_lru_locks osc
9725         # there may be some slab objects cached per core
9726         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9727         local before=$(num_objects)
9728         local count=$((512 * cpus))
9729         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9730         local margin=$((count / 10))
9731         if [[ -f $slab_lic/aliases ]]; then
9732                 local aliases=$(cat $slab_lic/aliases)
9733                 (( aliases > 0 )) && margin=$((margin * aliases))
9734         fi
9735
9736         echo "before slab objects: $before"
9737         for i in $(seq $count); do
9738                 touch $DIR/$tfile
9739                 rm -f $DIR/$tfile
9740         done
9741         cancel_lru_locks osc
9742         local after=$(num_objects)
9743         echo "created: $count, after slab objects: $after"
9744         # shared slab counts are not very accurate, allow significant margin
9745         # the main goal is that the cache growth is not permanently > $count
9746         while (( after > before + margin )); do
9747                 sleep 1
9748                 after=$(num_objects)
9749                 wait=$((wait + 1))
9750                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9751                 if (( wait > 60 )); then
9752                         error "inode slab grew from $before+$margin to $after"
9753                 fi
9754         done
9755 }
9756 run_test 76a "confirm clients recycle inodes properly ===="
9757
9758 test_76b() {
9759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9760         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9761
9762         local count=512
9763         local before=$(num_objects)
9764
9765         for i in $(seq $count); do
9766                 mkdir $DIR/$tdir
9767                 rmdir $DIR/$tdir
9768         done
9769
9770         local after=$(num_objects)
9771         local wait=0
9772
9773         while (( after > before )); do
9774                 sleep 1
9775                 after=$(num_objects)
9776                 wait=$((wait + 1))
9777                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9778                 if (( wait > 60 )); then
9779                         error "inode slab grew from $before to $after"
9780                 fi
9781         done
9782
9783         echo "slab objects before: $before, after: $after"
9784 }
9785 run_test 76b "confirm clients recycle directory inodes properly ===="
9786
9787 export ORIG_CSUM=""
9788 set_checksums()
9789 {
9790         # Note: in sptlrpc modes which enable its own bulk checksum, the
9791         # original crc32_le bulk checksum will be automatically disabled,
9792         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9793         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9794         # In this case set_checksums() will not be no-op, because sptlrpc
9795         # bulk checksum will be enabled all through the test.
9796
9797         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9798         lctl set_param -n osc.*.checksums $1
9799         return 0
9800 }
9801
9802 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9803                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9804 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9805                              tr -d [] | head -n1)}
9806 set_checksum_type()
9807 {
9808         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9809         rc=$?
9810         log "set checksum type to $1, rc = $rc"
9811         return $rc
9812 }
9813
9814 get_osc_checksum_type()
9815 {
9816         # arugment 1: OST name, like OST0000
9817         ost=$1
9818         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9819                         sed 's/.*\[\(.*\)\].*/\1/g')
9820         rc=$?
9821         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9822         echo $checksum_type
9823 }
9824
9825 F77_TMP=$TMP/f77-temp
9826 F77SZ=8
9827 setup_f77() {
9828         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9829                 error "error writing to $F77_TMP"
9830 }
9831
9832 test_77a() { # bug 10889
9833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9834         $GSS && skip_env "could not run with gss"
9835
9836         [ ! -f $F77_TMP ] && setup_f77
9837         set_checksums 1
9838         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9839         set_checksums 0
9840         rm -f $DIR/$tfile
9841 }
9842 run_test 77a "normal checksum read/write operation"
9843
9844 test_77b() { # bug 10889
9845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9846         $GSS && skip_env "could not run with gss"
9847
9848         [ ! -f $F77_TMP ] && setup_f77
9849         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9850         $LCTL set_param fail_loc=0x80000409
9851         set_checksums 1
9852
9853         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9854                 error "dd error: $?"
9855         $LCTL set_param fail_loc=0
9856
9857         for algo in $CKSUM_TYPES; do
9858                 cancel_lru_locks osc
9859                 set_checksum_type $algo
9860                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9861                 $LCTL set_param fail_loc=0x80000408
9862                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9863                 $LCTL set_param fail_loc=0
9864         done
9865         set_checksums 0
9866         set_checksum_type $ORIG_CSUM_TYPE
9867         rm -f $DIR/$tfile
9868 }
9869 run_test 77b "checksum error on client write, read"
9870
9871 cleanup_77c() {
9872         trap 0
9873         set_checksums 0
9874         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9875         $check_ost &&
9876                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9877         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9878         $check_ost && [ -n "$ost_file_prefix" ] &&
9879                 do_facet ost1 rm -f ${ost_file_prefix}\*
9880 }
9881
9882 test_77c() {
9883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9884         $GSS && skip_env "could not run with gss"
9885         remote_ost_nodsh && skip "remote OST with nodsh"
9886
9887         local bad1
9888         local osc_file_prefix
9889         local osc_file
9890         local check_ost=false
9891         local ost_file_prefix
9892         local ost_file
9893         local orig_cksum
9894         local dump_cksum
9895         local fid
9896
9897         # ensure corruption will occur on first OSS/OST
9898         $LFS setstripe -i 0 $DIR/$tfile
9899
9900         [ ! -f $F77_TMP ] && setup_f77
9901         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9902                 error "dd write error: $?"
9903         fid=$($LFS path2fid $DIR/$tfile)
9904
9905         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9906         then
9907                 check_ost=true
9908                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9909                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9910         else
9911                 echo "OSS do not support bulk pages dump upon error"
9912         fi
9913
9914         osc_file_prefix=$($LCTL get_param -n debug_path)
9915         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9916
9917         trap cleanup_77c EXIT
9918
9919         set_checksums 1
9920         # enable bulk pages dump upon error on Client
9921         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9922         # enable bulk pages dump upon error on OSS
9923         $check_ost &&
9924                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9925
9926         # flush Client cache to allow next read to reach OSS
9927         cancel_lru_locks osc
9928
9929         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9930         $LCTL set_param fail_loc=0x80000408
9931         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9932         $LCTL set_param fail_loc=0
9933
9934         rm -f $DIR/$tfile
9935
9936         # check cksum dump on Client
9937         osc_file=$(ls ${osc_file_prefix}*)
9938         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9939         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9940         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9941         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9942         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9943                      cksum)
9944         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9945         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9946                 error "dump content does not match on Client"
9947
9948         $check_ost || skip "No need to check cksum dump on OSS"
9949
9950         # check cksum dump on OSS
9951         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9952         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9953         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9954         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9955         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9956                 error "dump content does not match on OSS"
9957
9958         cleanup_77c
9959 }
9960 run_test 77c "checksum error on client read with debug"
9961
9962 test_77d() { # bug 10889
9963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9964         $GSS && skip_env "could not run with gss"
9965
9966         stack_trap "rm -f $DIR/$tfile"
9967         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9968         $LCTL set_param fail_loc=0x80000409
9969         set_checksums 1
9970         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9971                 error "direct write: rc=$?"
9972         $LCTL set_param fail_loc=0
9973         set_checksums 0
9974
9975         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9976         $LCTL set_param fail_loc=0x80000408
9977         set_checksums 1
9978         cancel_lru_locks osc
9979         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9980                 error "direct read: rc=$?"
9981         $LCTL set_param fail_loc=0
9982         set_checksums 0
9983 }
9984 run_test 77d "checksum error on OST direct write, read"
9985
9986 test_77f() { # bug 10889
9987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9988         $GSS && skip_env "could not run with gss"
9989
9990         set_checksums 1
9991         stack_trap "rm -f $DIR/$tfile"
9992         for algo in $CKSUM_TYPES; do
9993                 cancel_lru_locks osc
9994                 set_checksum_type $algo
9995                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9996                 $LCTL set_param fail_loc=0x409
9997                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9998                         error "direct write succeeded"
9999                 $LCTL set_param fail_loc=0
10000         done
10001         set_checksum_type $ORIG_CSUM_TYPE
10002         set_checksums 0
10003 }
10004 run_test 77f "repeat checksum error on write (expect error)"
10005
10006 test_77g() { # bug 10889
10007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10008         $GSS && skip_env "could not run with gss"
10009         remote_ost_nodsh && skip "remote OST with nodsh"
10010
10011         [ ! -f $F77_TMP ] && setup_f77
10012
10013         local file=$DIR/$tfile
10014         stack_trap "rm -f $file" EXIT
10015
10016         $LFS setstripe -c 1 -i 0 $file
10017         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10018         do_facet ost1 lctl set_param fail_loc=0x8000021a
10019         set_checksums 1
10020         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10021                 error "write error: rc=$?"
10022         do_facet ost1 lctl set_param fail_loc=0
10023         set_checksums 0
10024
10025         cancel_lru_locks osc
10026         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10027         do_facet ost1 lctl set_param fail_loc=0x8000021b
10028         set_checksums 1
10029         cmp $F77_TMP $file || error "file compare failed"
10030         do_facet ost1 lctl set_param fail_loc=0
10031         set_checksums 0
10032 }
10033 run_test 77g "checksum error on OST write, read"
10034
10035 test_77k() { # LU-10906
10036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10037         $GSS && skip_env "could not run with gss"
10038
10039         local cksum_param="osc.$FSNAME*.checksums"
10040         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10041         local checksum
10042         local i
10043
10044         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10045         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10046         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10047
10048         for i in 0 1; do
10049                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10050                         error "failed to set checksum=$i on MGS"
10051                 wait_update $HOSTNAME "$get_checksum" $i
10052                 #remount
10053                 echo "remount client, checksum should be $i"
10054                 remount_client $MOUNT || error "failed to remount client"
10055                 checksum=$(eval $get_checksum)
10056                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10057         done
10058         # remove persistent param to avoid races with checksum mountopt below
10059         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10060                 error "failed to delete checksum on MGS"
10061
10062         for opt in "checksum" "nochecksum"; do
10063                 #remount with mount option
10064                 echo "remount client with option $opt, checksum should be $i"
10065                 umount_client $MOUNT || error "failed to umount client"
10066                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10067                         error "failed to mount client with option '$opt'"
10068                 checksum=$(eval $get_checksum)
10069                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10070                 i=$((i - 1))
10071         done
10072
10073         remount_client $MOUNT || error "failed to remount client"
10074 }
10075 run_test 77k "enable/disable checksum correctly"
10076
10077 test_77l() {
10078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10079         $GSS && skip_env "could not run with gss"
10080
10081         set_checksums 1
10082         stack_trap "set_checksums $ORIG_CSUM" EXIT
10083         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10084
10085         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10086
10087         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10088         for algo in $CKSUM_TYPES; do
10089                 set_checksum_type $algo || error "fail to set checksum type $algo"
10090                 osc_algo=$(get_osc_checksum_type OST0000)
10091                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10092
10093                 # no locks, no reqs to let the connection idle
10094                 cancel_lru_locks osc
10095                 lru_resize_disable osc
10096                 wait_osc_import_state client ost1 IDLE
10097
10098                 # ensure ost1 is connected
10099                 stat $DIR/$tfile >/dev/null || error "can't stat"
10100                 wait_osc_import_state client ost1 FULL
10101
10102                 osc_algo=$(get_osc_checksum_type OST0000)
10103                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10104         done
10105         return 0
10106 }
10107 run_test 77l "preferred checksum type is remembered after reconnected"
10108
10109 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10110 rm -f $F77_TMP
10111 unset F77_TMP
10112
10113 test_77m() {
10114         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10115                 skip "Need at least version 2.14.52"
10116         local param=checksum_speed
10117
10118         $LCTL get_param $param || error "reading $param failed"
10119
10120         csum_speeds=$($LCTL get_param -n $param)
10121
10122         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10123                 error "known checksum types are missing"
10124 }
10125 run_test 77m "Verify checksum_speed is correctly read"
10126
10127 check_filefrag_77n() {
10128         local nr_ext=0
10129         local starts=()
10130         local ends=()
10131
10132         while read extidx a b start end rest; do
10133                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10134                         nr_ext=$(( $nr_ext + 1 ))
10135                         starts+=( ${start%..} )
10136                         ends+=( ${end%:} )
10137                 fi
10138         done < <( filefrag -sv $1 )
10139
10140         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10141         return 1
10142 }
10143
10144 test_77n() {
10145         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10146
10147         touch $DIR/$tfile
10148         $TRUNCATE $DIR/$tfile 0
10149         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10150         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10151         check_filefrag_77n $DIR/$tfile ||
10152                 skip "$tfile blocks not contiguous around hole"
10153
10154         set_checksums 1
10155         stack_trap "set_checksums $ORIG_CSUM" EXIT
10156         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10157         stack_trap "rm -f $DIR/$tfile"
10158
10159         for algo in $CKSUM_TYPES; do
10160                 if [[ "$algo" =~ ^t10 ]]; then
10161                         set_checksum_type $algo ||
10162                                 error "fail to set checksum type $algo"
10163                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10164                                 error "fail to read $tfile with $algo"
10165                 fi
10166         done
10167         rm -f $DIR/$tfile
10168         return 0
10169 }
10170 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10171
10172 test_77o() {
10173         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10174                 skip "Need MDS version at least 2.14.55"
10175         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10176                 skip "Need OST version at least 2.14.55"
10177         local ofd=obdfilter
10178         local mdt=mdt
10179
10180         # print OST checksum_type
10181         echo "$ofd.$FSNAME-*.checksum_type:"
10182         do_nodes $(comma_list $(osts_nodes)) \
10183                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10184
10185         # print MDT checksum_type
10186         echo "$mdt.$FSNAME-*.checksum_type:"
10187         do_nodes $(comma_list $(mdts_nodes)) \
10188                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10189
10190         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10191                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10192
10193         (( $o_count == $OSTCOUNT )) ||
10194                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10195
10196         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10197                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10198
10199         (( $m_count == $MDSCOUNT )) ||
10200                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10201 }
10202 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10203
10204 cleanup_test_78() {
10205         trap 0
10206         rm -f $DIR/$tfile
10207 }
10208
10209 test_78() { # bug 10901
10210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10211         remote_ost || skip_env "local OST"
10212
10213         NSEQ=5
10214         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10215         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10216         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10217         echo "MemTotal: $MEMTOTAL"
10218
10219         # reserve 256MB of memory for the kernel and other running processes,
10220         # and then take 1/2 of the remaining memory for the read/write buffers.
10221         if [ $MEMTOTAL -gt 512 ] ;then
10222                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10223         else
10224                 # for those poor memory-starved high-end clusters...
10225                 MEMTOTAL=$((MEMTOTAL / 2))
10226         fi
10227         echo "Mem to use for directio: $MEMTOTAL"
10228
10229         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10230         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10231         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10232         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10233                 head -n1)
10234         echo "Smallest OST: $SMALLESTOST"
10235         [[ $SMALLESTOST -lt 10240 ]] &&
10236                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10237
10238         trap cleanup_test_78 EXIT
10239
10240         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10241                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10242
10243         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10244         echo "File size: $F78SIZE"
10245         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10246         for i in $(seq 1 $NSEQ); do
10247                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10248                 echo directIO rdwr round $i of $NSEQ
10249                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10250         done
10251
10252         cleanup_test_78
10253 }
10254 run_test 78 "handle large O_DIRECT writes correctly ============"
10255
10256 test_79() { # bug 12743
10257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10258
10259         wait_delete_completed
10260
10261         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10262         BKFREE=$(calc_osc_kbytes kbytesfree)
10263         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10264
10265         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10266         DFTOTAL=`echo $STRING | cut -d, -f1`
10267         DFUSED=`echo $STRING  | cut -d, -f2`
10268         DFAVAIL=`echo $STRING | cut -d, -f3`
10269         DFFREE=$(($DFTOTAL - $DFUSED))
10270
10271         ALLOWANCE=$((64 * $OSTCOUNT))
10272
10273         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10274            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10275                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10276         fi
10277         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10278            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10279                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10280         fi
10281         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10282            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10283                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10284         fi
10285 }
10286 run_test 79 "df report consistency check ======================="
10287
10288 test_80() { # bug 10718
10289         remote_ost_nodsh && skip "remote OST with nodsh"
10290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10291
10292         # relax strong synchronous semantics for slow backends like ZFS
10293         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10294                 local soc="obdfilter.*.sync_lock_cancel"
10295                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10296
10297                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10298                 if [ -z "$save" ]; then
10299                         soc="obdfilter.*.sync_on_lock_cancel"
10300                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10301                 fi
10302
10303                 if [ "$save" != "never" ]; then
10304                         local hosts=$(comma_list $(osts_nodes))
10305
10306                         do_nodes $hosts $LCTL set_param $soc=never
10307                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10308                 fi
10309         fi
10310
10311         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10312         sync; sleep 1; sync
10313         local before=$(date +%s)
10314         cancel_lru_locks osc
10315         local after=$(date +%s)
10316         local diff=$((after - before))
10317         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10318
10319         rm -f $DIR/$tfile
10320 }
10321 run_test 80 "Page eviction is equally fast at high offsets too"
10322
10323 test_81a() { # LU-456
10324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10325         remote_ost_nodsh && skip "remote OST with nodsh"
10326
10327         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10328         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10329         do_facet ost1 lctl set_param fail_loc=0x80000228
10330
10331         # write should trigger a retry and success
10332         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10333         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10334         RC=$?
10335         if [ $RC -ne 0 ] ; then
10336                 error "write should success, but failed for $RC"
10337         fi
10338 }
10339 run_test 81a "OST should retry write when get -ENOSPC ==============="
10340
10341 test_81b() { # LU-456
10342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10343         remote_ost_nodsh && skip "remote OST with nodsh"
10344
10345         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10346         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10347         do_facet ost1 lctl set_param fail_loc=0x228
10348
10349         # write should retry several times and return -ENOSPC finally
10350         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10351         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10352         RC=$?
10353         ENOSPC=28
10354         if [ $RC -ne $ENOSPC ] ; then
10355                 error "dd should fail for -ENOSPC, but succeed."
10356         fi
10357 }
10358 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10359
10360 test_99() {
10361         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10362
10363         test_mkdir $DIR/$tdir.cvsroot
10364         chown $RUNAS_ID $DIR/$tdir.cvsroot
10365
10366         cd $TMP
10367         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10368
10369         cd /etc/init.d
10370         # some versions of cvs import exit(1) when asked to import links or
10371         # files they can't read.  ignore those files.
10372         local toignore=$(find . -type l -printf '-I %f\n' -o \
10373                          ! -perm /4 -printf '-I %f\n')
10374         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10375                 $tdir.reposname vtag rtag
10376
10377         cd $DIR
10378         test_mkdir $DIR/$tdir.reposname
10379         chown $RUNAS_ID $DIR/$tdir.reposname
10380         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10381
10382         cd $DIR/$tdir.reposname
10383         $RUNAS touch foo99
10384         $RUNAS cvs add -m 'addmsg' foo99
10385         $RUNAS cvs update
10386         $RUNAS cvs commit -m 'nomsg' foo99
10387         rm -fr $DIR/$tdir.cvsroot
10388 }
10389 run_test 99 "cvs strange file/directory operations"
10390
10391 test_100() {
10392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10393         [[ "$NETTYPE" =~ tcp ]] ||
10394                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10395         remote_ost_nodsh && skip "remote OST with nodsh"
10396         remote_mds_nodsh && skip "remote MDS with nodsh"
10397         remote_servers ||
10398                 skip "useless for local single node setup"
10399
10400         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10401                 [ "$PROT" != "tcp" ] && continue
10402                 RPORT=$(echo $REMOTE | cut -d: -f2)
10403                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10404
10405                 rc=0
10406                 LPORT=`echo $LOCAL | cut -d: -f2`
10407                 if [ $LPORT -ge 1024 ]; then
10408                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10409                         netstat -tna
10410                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10411                 fi
10412         done
10413         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10414 }
10415 run_test 100 "check local port using privileged port ==========="
10416
10417 function get_named_value()
10418 {
10419     local tag=$1
10420
10421     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10422 }
10423
10424 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10425                    awk '/^max_cached_mb/ { print $2 }')
10426
10427 cleanup_101a() {
10428         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10429         trap 0
10430 }
10431
10432 test_101a() {
10433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10434
10435         local s
10436         local discard
10437         local nreads=10000
10438         local cache_limit=32
10439
10440         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10441         trap cleanup_101a EXIT
10442         $LCTL set_param -n llite.*.read_ahead_stats=0
10443         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10444
10445         #
10446         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10447         #
10448         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10449         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10450
10451         discard=0
10452         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10453                    get_named_value 'read.but.discarded'); do
10454                         discard=$(($discard + $s))
10455         done
10456         cleanup_101a
10457
10458         $LCTL get_param osc.*-osc*.rpc_stats
10459         $LCTL get_param llite.*.read_ahead_stats
10460
10461         # Discard is generally zero, but sometimes a few random reads line up
10462         # and trigger larger readahead, which is wasted & leads to discards.
10463         if [[ $(($discard)) -gt $nreads ]]; then
10464                 error "too many ($discard) discarded pages"
10465         fi
10466         rm -f $DIR/$tfile || true
10467 }
10468 run_test 101a "check read-ahead for random reads"
10469
10470 setup_test101bc() {
10471         test_mkdir $DIR/$tdir
10472         local ssize=$1
10473         local FILE_LENGTH=$2
10474         STRIPE_OFFSET=0
10475
10476         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10477
10478         local list=$(comma_list $(osts_nodes))
10479         set_osd_param $list '' read_cache_enable 0
10480         set_osd_param $list '' writethrough_cache_enable 0
10481
10482         trap cleanup_test101bc EXIT
10483         # prepare the read-ahead file
10484         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10485
10486         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10487                                 count=$FILE_SIZE_MB 2> /dev/null
10488
10489 }
10490
10491 cleanup_test101bc() {
10492         trap 0
10493         rm -rf $DIR/$tdir
10494         rm -f $DIR/$tfile
10495
10496         local list=$(comma_list $(osts_nodes))
10497         set_osd_param $list '' read_cache_enable 1
10498         set_osd_param $list '' writethrough_cache_enable 1
10499 }
10500
10501 calc_total() {
10502         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10503 }
10504
10505 ra_check_101() {
10506         local read_size=$1
10507         local stripe_size=$2
10508         local stride_length=$((stripe_size / read_size))
10509         local stride_width=$((stride_length * OSTCOUNT))
10510         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10511                                 (stride_width - stride_length) ))
10512         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10513                   get_named_value 'read.but.discarded' | calc_total)
10514
10515         if [[ $discard -gt $discard_limit ]]; then
10516                 $LCTL get_param llite.*.read_ahead_stats
10517                 error "($discard) discarded pages with size (${read_size})"
10518         else
10519                 echo "Read-ahead success for size ${read_size}"
10520         fi
10521 }
10522
10523 test_101b() {
10524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10525         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10526
10527         local STRIPE_SIZE=1048576
10528         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10529
10530         if [ $SLOW == "yes" ]; then
10531                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10532         else
10533                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10534         fi
10535
10536         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10537
10538         # prepare the read-ahead file
10539         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10540         cancel_lru_locks osc
10541         for BIDX in 2 4 8 16 32 64 128 256
10542         do
10543                 local BSIZE=$((BIDX*4096))
10544                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10545                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10546                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10547                 $LCTL set_param -n llite.*.read_ahead_stats=0
10548                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10549                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10550                 cancel_lru_locks osc
10551                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10552         done
10553         cleanup_test101bc
10554         true
10555 }
10556 run_test 101b "check stride-io mode read-ahead ================="
10557
10558 test_101c() {
10559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10560
10561         local STRIPE_SIZE=1048576
10562         local FILE_LENGTH=$((STRIPE_SIZE*100))
10563         local nreads=10000
10564         local rsize=65536
10565         local osc_rpc_stats
10566
10567         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10568
10569         cancel_lru_locks osc
10570         $LCTL set_param osc.*.rpc_stats=0
10571         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10572         $LCTL get_param osc.*.rpc_stats
10573         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10574                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10575                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10576                 local size
10577
10578                 if [ $lines -le 20 ]; then
10579                         echo "continue debug"
10580                         continue
10581                 fi
10582                 for size in 1 2 4 8; do
10583                         local rpc=$(echo "$stats" |
10584                                     awk '($1 == "'$size':") {print $2; exit; }')
10585                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10586                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10587                 done
10588                 echo "$osc_rpc_stats check passed!"
10589         done
10590         cleanup_test101bc
10591         true
10592 }
10593 run_test 101c "check stripe_size aligned read-ahead"
10594
10595 test_101d() {
10596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10597
10598         local file=$DIR/$tfile
10599         local sz_MB=${FILESIZE_101d:-80}
10600         local ra_MB=${READAHEAD_MB:-40}
10601
10602         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10603         [ $free_MB -lt $sz_MB ] &&
10604                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10605
10606         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10607         $LFS setstripe -c -1 $file || error "setstripe failed"
10608
10609         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10610         echo Cancel LRU locks on lustre client to flush the client cache
10611         cancel_lru_locks osc
10612
10613         echo Disable read-ahead
10614         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10615         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10616         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10617         $LCTL get_param -n llite.*.max_read_ahead_mb
10618
10619         echo "Reading the test file $file with read-ahead disabled"
10620         local sz_KB=$((sz_MB * 1024 / 4))
10621         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10622         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10623         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10624                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10625
10626         echo "Cancel LRU locks on lustre client to flush the client cache"
10627         cancel_lru_locks osc
10628         echo Enable read-ahead with ${ra_MB}MB
10629         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10630
10631         echo "Reading the test file $file with read-ahead enabled"
10632         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10633                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10634
10635         echo "read-ahead disabled time read $raOFF"
10636         echo "read-ahead enabled time read $raON"
10637
10638         rm -f $file
10639         wait_delete_completed
10640
10641         # use awk for this check instead of bash because it handles decimals
10642         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10643                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10644 }
10645 run_test 101d "file read with and without read-ahead enabled"
10646
10647 test_101e() {
10648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10649
10650         local file=$DIR/$tfile
10651         local size_KB=500  #KB
10652         local count=100
10653         local bsize=1024
10654
10655         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10656         local need_KB=$((count * size_KB))
10657         [[ $free_KB -le $need_KB ]] &&
10658                 skip_env "Need free space $need_KB, have $free_KB"
10659
10660         echo "Creating $count ${size_KB}K test files"
10661         for ((i = 0; i < $count; i++)); do
10662                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10663         done
10664
10665         echo "Cancel LRU locks on lustre client to flush the client cache"
10666         cancel_lru_locks $OSC
10667
10668         echo "Reset readahead stats"
10669         $LCTL set_param -n llite.*.read_ahead_stats=0
10670
10671         for ((i = 0; i < $count; i++)); do
10672                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10673         done
10674
10675         $LCTL get_param llite.*.max_cached_mb
10676         $LCTL get_param llite.*.read_ahead_stats
10677         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10678                      get_named_value 'misses' | calc_total)
10679
10680         for ((i = 0; i < $count; i++)); do
10681                 rm -rf $file.$i 2>/dev/null
10682         done
10683
10684         #10000 means 20% reads are missing in readahead
10685         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10686 }
10687 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10688
10689 test_101f() {
10690         which iozone || skip_env "no iozone installed"
10691
10692         local old_debug=$($LCTL get_param debug)
10693         old_debug=${old_debug#*=}
10694         $LCTL set_param debug="reada mmap"
10695
10696         # create a test file
10697         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10698
10699         echo Cancel LRU locks on lustre client to flush the client cache
10700         cancel_lru_locks osc
10701
10702         echo Reset readahead stats
10703         $LCTL set_param -n llite.*.read_ahead_stats=0
10704
10705         echo mmap read the file with small block size
10706         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10707                 > /dev/null 2>&1
10708
10709         echo checking missing pages
10710         $LCTL get_param llite.*.read_ahead_stats
10711         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10712                         get_named_value 'misses' | calc_total)
10713
10714         $LCTL set_param debug="$old_debug"
10715         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10716         rm -f $DIR/$tfile
10717 }
10718 run_test 101f "check mmap read performance"
10719
10720 test_101g_brw_size_test() {
10721         local mb=$1
10722         local pages=$((mb * 1048576 / PAGE_SIZE))
10723         local file=$DIR/$tfile
10724
10725         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10726                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10727         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10728                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10729                         return 2
10730         done
10731
10732         stack_trap "rm -f $file" EXIT
10733         $LCTL set_param -n osc.*.rpc_stats=0
10734
10735         # 10 RPCs should be enough for the test
10736         local count=10
10737         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10738                 { error "dd write ${mb} MB blocks failed"; return 3; }
10739         cancel_lru_locks osc
10740         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10741                 { error "dd write ${mb} MB blocks failed"; return 4; }
10742
10743         # calculate number of full-sized read and write RPCs
10744         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10745                 sed -n '/pages per rpc/,/^$/p' |
10746                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10747                 END { print reads,writes }'))
10748         # allow one extra full-sized read RPC for async readahead
10749         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10750                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10751         [[ ${rpcs[1]} == $count ]] ||
10752                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10753 }
10754
10755 test_101g() {
10756         remote_ost_nodsh && skip "remote OST with nodsh"
10757
10758         local rpcs
10759         local osts=$(get_facets OST)
10760         local list=$(comma_list $(osts_nodes))
10761         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10762         local brw_size="obdfilter.*.brw_size"
10763
10764         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10765
10766         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10767
10768         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10769                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10770                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10771            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10772                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10773                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10774
10775                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10776                         suffix="M"
10777
10778                 if [[ $orig_mb -lt 16 ]]; then
10779                         save_lustre_params $osts "$brw_size" > $p
10780                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10781                                 error "set 16MB RPC size failed"
10782
10783                         echo "remount client to enable new RPC size"
10784                         remount_client $MOUNT || error "remount_client failed"
10785                 fi
10786
10787                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10788                 # should be able to set brw_size=12, but no rpc_stats for that
10789                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10790         fi
10791
10792         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10793
10794         if [[ $orig_mb -lt 16 ]]; then
10795                 restore_lustre_params < $p
10796                 remount_client $MOUNT || error "remount_client restore failed"
10797         fi
10798
10799         rm -f $p $DIR/$tfile
10800 }
10801 run_test 101g "Big bulk(4/16 MiB) readahead"
10802
10803 test_101h() {
10804         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10805
10806         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10807                 error "dd 70M file failed"
10808         echo Cancel LRU locks on lustre client to flush the client cache
10809         cancel_lru_locks osc
10810
10811         echo "Reset readahead stats"
10812         $LCTL set_param -n llite.*.read_ahead_stats 0
10813
10814         echo "Read 10M of data but cross 64M bundary"
10815         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10816         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10817                      get_named_value 'misses' | calc_total)
10818         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10819         rm -f $p $DIR/$tfile
10820 }
10821 run_test 101h "Readahead should cover current read window"
10822
10823 test_101i() {
10824         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10825                 error "dd 10M file failed"
10826
10827         local max_per_file_mb=$($LCTL get_param -n \
10828                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10829         cancel_lru_locks osc
10830         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10831         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10832                 error "set max_read_ahead_per_file_mb to 1 failed"
10833
10834         echo "Reset readahead stats"
10835         $LCTL set_param llite.*.read_ahead_stats=0
10836
10837         dd if=$DIR/$tfile of=/dev/null bs=2M
10838
10839         $LCTL get_param llite.*.read_ahead_stats
10840         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10841                      awk '/misses/ { print $2 }')
10842         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10843         rm -f $DIR/$tfile
10844 }
10845 run_test 101i "allow current readahead to exceed reservation"
10846
10847 test_101j() {
10848         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10849                 error "setstripe $DIR/$tfile failed"
10850         local file_size=$((1048576 * 16))
10851         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10852         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10853
10854         echo Disable read-ahead
10855         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10856
10857         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10858         for blk in $PAGE_SIZE 1048576 $file_size; do
10859                 cancel_lru_locks osc
10860                 echo "Reset readahead stats"
10861                 $LCTL set_param -n llite.*.read_ahead_stats=0
10862                 local count=$(($file_size / $blk))
10863                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10864                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10865                              get_named_value 'failed.to.fast.read' | calc_total)
10866                 $LCTL get_param -n llite.*.read_ahead_stats
10867                 [ $miss -eq $count ] || error "expected $count got $miss"
10868         done
10869
10870         rm -f $p $DIR/$tfile
10871 }
10872 run_test 101j "A complete read block should be submitted when no RA"
10873
10874 setup_test102() {
10875         test_mkdir $DIR/$tdir
10876         chown $RUNAS_ID $DIR/$tdir
10877         STRIPE_SIZE=65536
10878         STRIPE_OFFSET=1
10879         STRIPE_COUNT=$OSTCOUNT
10880         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10881
10882         trap cleanup_test102 EXIT
10883         cd $DIR
10884         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10885         cd $DIR/$tdir
10886         for num in 1 2 3 4; do
10887                 for count in $(seq 1 $STRIPE_COUNT); do
10888                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10889                                 local size=`expr $STRIPE_SIZE \* $num`
10890                                 local file=file"$num-$idx-$count"
10891                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10892                         done
10893                 done
10894         done
10895
10896         cd $DIR
10897         $1 tar cf $TMP/f102.tar $tdir --xattrs
10898 }
10899
10900 cleanup_test102() {
10901         trap 0
10902         rm -f $TMP/f102.tar
10903         rm -rf $DIR/d0.sanity/d102
10904 }
10905
10906 test_102a() {
10907         [ "$UID" != 0 ] && skip "must run as root"
10908         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10909                 skip_env "must have user_xattr"
10910
10911         [ -z "$(which setfattr 2>/dev/null)" ] &&
10912                 skip_env "could not find setfattr"
10913
10914         local testfile=$DIR/$tfile
10915
10916         touch $testfile
10917         echo "set/get xattr..."
10918         setfattr -n trusted.name1 -v value1 $testfile ||
10919                 error "setfattr -n trusted.name1=value1 $testfile failed"
10920         getfattr -n trusted.name1 $testfile 2> /dev/null |
10921           grep "trusted.name1=.value1" ||
10922                 error "$testfile missing trusted.name1=value1"
10923
10924         setfattr -n user.author1 -v author1 $testfile ||
10925                 error "setfattr -n user.author1=author1 $testfile failed"
10926         getfattr -n user.author1 $testfile 2> /dev/null |
10927           grep "user.author1=.author1" ||
10928                 error "$testfile missing trusted.author1=author1"
10929
10930         echo "listxattr..."
10931         setfattr -n trusted.name2 -v value2 $testfile ||
10932                 error "$testfile unable to set trusted.name2"
10933         setfattr -n trusted.name3 -v value3 $testfile ||
10934                 error "$testfile unable to set trusted.name3"
10935         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10936             grep "trusted.name" | wc -l) -eq 3 ] ||
10937                 error "$testfile missing 3 trusted.name xattrs"
10938
10939         setfattr -n user.author2 -v author2 $testfile ||
10940                 error "$testfile unable to set user.author2"
10941         setfattr -n user.author3 -v author3 $testfile ||
10942                 error "$testfile unable to set user.author3"
10943         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10944             grep "user.author" | wc -l) -eq 3 ] ||
10945                 error "$testfile missing 3 user.author xattrs"
10946
10947         echo "remove xattr..."
10948         setfattr -x trusted.name1 $testfile ||
10949                 error "$testfile error deleting trusted.name1"
10950         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10951                 error "$testfile did not delete trusted.name1 xattr"
10952
10953         setfattr -x user.author1 $testfile ||
10954                 error "$testfile error deleting user.author1"
10955         echo "set lustre special xattr ..."
10956         $LFS setstripe -c1 $testfile
10957         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10958                 awk -F "=" '/trusted.lov/ { print $2 }' )
10959         setfattr -n "trusted.lov" -v $lovea $testfile ||
10960                 error "$testfile doesn't ignore setting trusted.lov again"
10961         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10962                 error "$testfile allow setting invalid trusted.lov"
10963         rm -f $testfile
10964 }
10965 run_test 102a "user xattr test =================================="
10966
10967 check_102b_layout() {
10968         local layout="$*"
10969         local testfile=$DIR/$tfile
10970
10971         echo "test layout '$layout'"
10972         $LFS setstripe $layout $testfile || error "setstripe failed"
10973         $LFS getstripe -y $testfile
10974
10975         echo "get/set/list trusted.lov xattr ..." # b=10930
10976         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10977         [[ "$value" =~ "trusted.lov" ]] ||
10978                 error "can't get trusted.lov from $testfile"
10979         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10980                 error "getstripe failed"
10981
10982         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10983
10984         value=$(cut -d= -f2 <<<$value)
10985         # LU-13168: truncated xattr should fail if short lov_user_md header
10986         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10987                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10988         for len in $lens; do
10989                 echo "setfattr $len $testfile.2"
10990                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10991                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10992         done
10993         local stripe_size=$($LFS getstripe -S $testfile.2)
10994         local stripe_count=$($LFS getstripe -c $testfile.2)
10995         [[ $stripe_size -eq 65536 ]] ||
10996                 error "stripe size $stripe_size != 65536"
10997         [[ $stripe_count -eq $stripe_count_orig ]] ||
10998                 error "stripe count $stripe_count != $stripe_count_orig"
10999         rm $testfile $testfile.2
11000 }
11001
11002 test_102b() {
11003         [ -z "$(which setfattr 2>/dev/null)" ] &&
11004                 skip_env "could not find setfattr"
11005         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11006
11007         # check plain layout
11008         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11009
11010         # and also check composite layout
11011         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11012
11013 }
11014 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11015
11016 test_102c() {
11017         [ -z "$(which setfattr 2>/dev/null)" ] &&
11018                 skip_env "could not find setfattr"
11019         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11020
11021         # b10930: get/set/list lustre.lov xattr
11022         echo "get/set/list lustre.lov xattr ..."
11023         test_mkdir $DIR/$tdir
11024         chown $RUNAS_ID $DIR/$tdir
11025         local testfile=$DIR/$tdir/$tfile
11026         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11027                 error "setstripe failed"
11028         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11029                 error "getstripe failed"
11030         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11031         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11032
11033         local testfile2=${testfile}2
11034         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11035                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11036
11037         $RUNAS $MCREATE $testfile2
11038         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11039         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11040         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11041         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11042         [ $stripe_count -eq $STRIPECOUNT ] ||
11043                 error "stripe count $stripe_count != $STRIPECOUNT"
11044 }
11045 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11046
11047 compare_stripe_info1() {
11048         local stripe_index_all_zero=true
11049
11050         for num in 1 2 3 4; do
11051                 for count in $(seq 1 $STRIPE_COUNT); do
11052                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11053                                 local size=$((STRIPE_SIZE * num))
11054                                 local file=file"$num-$offset-$count"
11055                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11056                                 [[ $stripe_size -ne $size ]] &&
11057                                     error "$file: size $stripe_size != $size"
11058                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11059                                 # allow fewer stripes to be created, ORI-601
11060                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11061                                     error "$file: count $stripe_count != $count"
11062                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11063                                 [[ $stripe_index -ne 0 ]] &&
11064                                         stripe_index_all_zero=false
11065                         done
11066                 done
11067         done
11068         $stripe_index_all_zero &&
11069                 error "all files are being extracted starting from OST index 0"
11070         return 0
11071 }
11072
11073 have_xattrs_include() {
11074         tar --help | grep -q xattrs-include &&
11075                 echo --xattrs-include="lustre.*"
11076 }
11077
11078 test_102d() {
11079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11081
11082         XINC=$(have_xattrs_include)
11083         setup_test102
11084         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11085         cd $DIR/$tdir/$tdir
11086         compare_stripe_info1
11087 }
11088 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11089
11090 test_102f() {
11091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11092         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11093
11094         XINC=$(have_xattrs_include)
11095         setup_test102
11096         test_mkdir $DIR/$tdir.restore
11097         cd $DIR
11098         tar cf - --xattrs $tdir | tar xf - \
11099                 -C $DIR/$tdir.restore --xattrs $XINC
11100         cd $DIR/$tdir.restore/$tdir
11101         compare_stripe_info1
11102 }
11103 run_test 102f "tar copy files, not keep osts"
11104
11105 grow_xattr() {
11106         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11107                 skip "must have user_xattr"
11108         [ -z "$(which setfattr 2>/dev/null)" ] &&
11109                 skip_env "could not find setfattr"
11110         [ -z "$(which getfattr 2>/dev/null)" ] &&
11111                 skip_env "could not find getfattr"
11112
11113         local xsize=${1:-1024}  # in bytes
11114         local file=$DIR/$tfile
11115         local value="$(generate_string $xsize)"
11116         local xbig=trusted.big
11117         local toobig=$2
11118
11119         touch $file
11120         log "save $xbig on $file"
11121         if [ -z "$toobig" ]
11122         then
11123                 setfattr -n $xbig -v $value $file ||
11124                         error "saving $xbig on $file failed"
11125         else
11126                 setfattr -n $xbig -v $value $file &&
11127                         error "saving $xbig on $file succeeded"
11128                 return 0
11129         fi
11130
11131         local orig=$(get_xattr_value $xbig $file)
11132         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11133
11134         local xsml=trusted.sml
11135         log "save $xsml on $file"
11136         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11137
11138         local new=$(get_xattr_value $xbig $file)
11139         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11140
11141         log "grow $xsml on $file"
11142         setfattr -n $xsml -v "$value" $file ||
11143                 error "growing $xsml on $file failed"
11144
11145         new=$(get_xattr_value $xbig $file)
11146         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11147         log "$xbig still valid after growing $xsml"
11148
11149         rm -f $file
11150 }
11151
11152 test_102h() { # bug 15777
11153         grow_xattr 1024
11154 }
11155 run_test 102h "grow xattr from inside inode to external block"
11156
11157 test_102ha() {
11158         large_xattr_enabled || skip_env "ea_inode feature disabled"
11159
11160         echo "setting xattr of max xattr size: $(max_xattr_size)"
11161         grow_xattr $(max_xattr_size)
11162
11163         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11164         echo "This should fail:"
11165         grow_xattr $(($(max_xattr_size) + 10)) 1
11166 }
11167 run_test 102ha "grow xattr from inside inode to external inode"
11168
11169 test_102i() { # bug 17038
11170         [ -z "$(which getfattr 2>/dev/null)" ] &&
11171                 skip "could not find getfattr"
11172
11173         touch $DIR/$tfile
11174         ln -s $DIR/$tfile $DIR/${tfile}link
11175         getfattr -n trusted.lov $DIR/$tfile ||
11176                 error "lgetxattr on $DIR/$tfile failed"
11177         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11178                 grep -i "no such attr" ||
11179                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11180         rm -f $DIR/$tfile $DIR/${tfile}link
11181 }
11182 run_test 102i "lgetxattr test on symbolic link ============"
11183
11184 test_102j() {
11185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11186         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11187
11188         XINC=$(have_xattrs_include)
11189         setup_test102 "$RUNAS"
11190         chown $RUNAS_ID $DIR/$tdir
11191         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11192         cd $DIR/$tdir/$tdir
11193         compare_stripe_info1 "$RUNAS"
11194 }
11195 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11196
11197 test_102k() {
11198         [ -z "$(which setfattr 2>/dev/null)" ] &&
11199                 skip "could not find setfattr"
11200
11201         touch $DIR/$tfile
11202         # b22187 just check that does not crash for regular file.
11203         setfattr -n trusted.lov $DIR/$tfile
11204         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11205         local test_kdir=$DIR/$tdir
11206         test_mkdir $test_kdir
11207         local default_size=$($LFS getstripe -S $test_kdir)
11208         local default_count=$($LFS getstripe -c $test_kdir)
11209         local default_offset=$($LFS getstripe -i $test_kdir)
11210         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11211                 error 'dir setstripe failed'
11212         setfattr -n trusted.lov $test_kdir
11213         local stripe_size=$($LFS getstripe -S $test_kdir)
11214         local stripe_count=$($LFS getstripe -c $test_kdir)
11215         local stripe_offset=$($LFS getstripe -i $test_kdir)
11216         [ $stripe_size -eq $default_size ] ||
11217                 error "stripe size $stripe_size != $default_size"
11218         [ $stripe_count -eq $default_count ] ||
11219                 error "stripe count $stripe_count != $default_count"
11220         [ $stripe_offset -eq $default_offset ] ||
11221                 error "stripe offset $stripe_offset != $default_offset"
11222         rm -rf $DIR/$tfile $test_kdir
11223 }
11224 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11225
11226 test_102l() {
11227         [ -z "$(which getfattr 2>/dev/null)" ] &&
11228                 skip "could not find getfattr"
11229
11230         # LU-532 trusted. xattr is invisible to non-root
11231         local testfile=$DIR/$tfile
11232
11233         touch $testfile
11234
11235         echo "listxattr as user..."
11236         chown $RUNAS_ID $testfile
11237         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11238             grep -q "trusted" &&
11239                 error "$testfile trusted xattrs are user visible"
11240
11241         return 0;
11242 }
11243 run_test 102l "listxattr size test =================================="
11244
11245 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11246         local path=$DIR/$tfile
11247         touch $path
11248
11249         listxattr_size_check $path || error "listattr_size_check $path failed"
11250 }
11251 run_test 102m "Ensure listxattr fails on small bufffer ========"
11252
11253 cleanup_test102
11254
11255 getxattr() { # getxattr path name
11256         # Return the base64 encoding of the value of xattr name on path.
11257         local path=$1
11258         local name=$2
11259
11260         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11261         # file: $path
11262         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11263         #
11264         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11265
11266         getfattr --absolute-names --encoding=base64 --name=$name $path |
11267                 awk -F= -v name=$name '$1 == name {
11268                         print substr($0, index($0, "=") + 1);
11269         }'
11270 }
11271
11272 test_102n() { # LU-4101 mdt: protect internal xattrs
11273         [ -z "$(which setfattr 2>/dev/null)" ] &&
11274                 skip "could not find setfattr"
11275         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11276         then
11277                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11278         fi
11279
11280         local file0=$DIR/$tfile.0
11281         local file1=$DIR/$tfile.1
11282         local xattr0=$TMP/$tfile.0
11283         local xattr1=$TMP/$tfile.1
11284         local namelist="lov lma lmv link fid version som hsm"
11285         local name
11286         local value
11287
11288         rm -rf $file0 $file1 $xattr0 $xattr1
11289         touch $file0 $file1
11290
11291         # Get 'before' xattrs of $file1.
11292         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11293
11294         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11295                 namelist+=" lfsck_namespace"
11296         for name in $namelist; do
11297                 # Try to copy xattr from $file0 to $file1.
11298                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11299
11300                 setfattr --name=trusted.$name --value="$value" $file1 ||
11301                         error "setxattr 'trusted.$name' failed"
11302
11303                 # Try to set a garbage xattr.
11304                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11305
11306                 if [[ x$name == "xlov" ]]; then
11307                         setfattr --name=trusted.lov --value="$value" $file1 &&
11308                         error "setxattr invalid 'trusted.lov' success"
11309                 else
11310                         setfattr --name=trusted.$name --value="$value" $file1 ||
11311                                 error "setxattr invalid 'trusted.$name' failed"
11312                 fi
11313
11314                 # Try to remove the xattr from $file1. We don't care if this
11315                 # appears to succeed or fail, we just don't want there to be
11316                 # any changes or crashes.
11317                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11318         done
11319
11320         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11321         then
11322                 name="lfsck_ns"
11323                 # Try to copy xattr from $file0 to $file1.
11324                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11325
11326                 setfattr --name=trusted.$name --value="$value" $file1 ||
11327                         error "setxattr 'trusted.$name' failed"
11328
11329                 # Try to set a garbage xattr.
11330                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11331
11332                 setfattr --name=trusted.$name --value="$value" $file1 ||
11333                         error "setxattr 'trusted.$name' failed"
11334
11335                 # Try to remove the xattr from $file1. We don't care if this
11336                 # appears to succeed or fail, we just don't want there to be
11337                 # any changes or crashes.
11338                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11339         fi
11340
11341         # Get 'after' xattrs of file1.
11342         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11343
11344         if ! diff $xattr0 $xattr1; then
11345                 error "before and after xattrs of '$file1' differ"
11346         fi
11347
11348         rm -rf $file0 $file1 $xattr0 $xattr1
11349
11350         return 0
11351 }
11352 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11353
11354 test_102p() { # LU-4703 setxattr did not check ownership
11355         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11356                 skip "MDS needs to be at least 2.5.56"
11357
11358         local testfile=$DIR/$tfile
11359
11360         touch $testfile
11361
11362         echo "setfacl as user..."
11363         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11364         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11365
11366         echo "setfattr as user..."
11367         setfacl -m "u:$RUNAS_ID:---" $testfile
11368         $RUNAS setfattr -x system.posix_acl_access $testfile
11369         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11370 }
11371 run_test 102p "check setxattr(2) correctly fails without permission"
11372
11373 test_102q() {
11374         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11375                 skip "MDS needs to be at least 2.6.92"
11376
11377         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11378 }
11379 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11380
11381 test_102r() {
11382         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11383                 skip "MDS needs to be at least 2.6.93"
11384
11385         touch $DIR/$tfile || error "touch"
11386         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11387         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11388         rm $DIR/$tfile || error "rm"
11389
11390         #normal directory
11391         mkdir -p $DIR/$tdir || error "mkdir"
11392         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11393         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11394         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11395                 error "$testfile error deleting user.author1"
11396         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11397                 grep "user.$(basename $tdir)" &&
11398                 error "$tdir did not delete user.$(basename $tdir)"
11399         rmdir $DIR/$tdir || error "rmdir"
11400
11401         #striped directory
11402         test_mkdir $DIR/$tdir
11403         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11404         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11405         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11406                 error "$testfile error deleting user.author1"
11407         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11408                 grep "user.$(basename $tdir)" &&
11409                 error "$tdir did not delete user.$(basename $tdir)"
11410         rmdir $DIR/$tdir || error "rm striped dir"
11411 }
11412 run_test 102r "set EAs with empty values"
11413
11414 test_102s() {
11415         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11416                 skip "MDS needs to be at least 2.11.52"
11417
11418         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11419
11420         save_lustre_params client "llite.*.xattr_cache" > $save
11421
11422         for cache in 0 1; do
11423                 lctl set_param llite.*.xattr_cache=$cache
11424
11425                 rm -f $DIR/$tfile
11426                 touch $DIR/$tfile || error "touch"
11427                 for prefix in lustre security system trusted user; do
11428                         # Note getxattr() may fail with 'Operation not
11429                         # supported' or 'No such attribute' depending
11430                         # on prefix and cache.
11431                         getfattr -n $prefix.n102s $DIR/$tfile &&
11432                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11433                 done
11434         done
11435
11436         restore_lustre_params < $save
11437 }
11438 run_test 102s "getting nonexistent xattrs should fail"
11439
11440 test_102t() {
11441         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11442                 skip "MDS needs to be at least 2.11.52"
11443
11444         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11445
11446         save_lustre_params client "llite.*.xattr_cache" > $save
11447
11448         for cache in 0 1; do
11449                 lctl set_param llite.*.xattr_cache=$cache
11450
11451                 for buf_size in 0 256; do
11452                         rm -f $DIR/$tfile
11453                         touch $DIR/$tfile || error "touch"
11454                         setfattr -n user.multiop $DIR/$tfile
11455                         $MULTIOP $DIR/$tfile oa$buf_size ||
11456                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11457                 done
11458         done
11459
11460         restore_lustre_params < $save
11461 }
11462 run_test 102t "zero length xattr values handled correctly"
11463
11464 run_acl_subtest()
11465 {
11466     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11467     return $?
11468 }
11469
11470 test_103a() {
11471         [ "$UID" != 0 ] && skip "must run as root"
11472         $GSS && skip_env "could not run under gss"
11473         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11474                 skip_env "must have acl enabled"
11475         [ -z "$(which setfacl 2>/dev/null)" ] &&
11476                 skip_env "could not find setfacl"
11477         remote_mds_nodsh && skip "remote MDS with nodsh"
11478
11479         gpasswd -a daemon bin                           # LU-5641
11480         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11481
11482         declare -a identity_old
11483
11484         for num in $(seq $MDSCOUNT); do
11485                 switch_identity $num true || identity_old[$num]=$?
11486         done
11487
11488         SAVE_UMASK=$(umask)
11489         umask 0022
11490         mkdir -p $DIR/$tdir
11491         cd $DIR/$tdir
11492
11493         echo "performing cp ..."
11494         run_acl_subtest cp || error "run_acl_subtest cp failed"
11495         echo "performing getfacl-noacl..."
11496         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11497         echo "performing misc..."
11498         run_acl_subtest misc || error  "misc test failed"
11499         echo "performing permissions..."
11500         run_acl_subtest permissions || error "permissions failed"
11501         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11502         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11503                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11504                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11505         then
11506                 echo "performing permissions xattr..."
11507                 run_acl_subtest permissions_xattr ||
11508                         error "permissions_xattr failed"
11509         fi
11510         echo "performing setfacl..."
11511         run_acl_subtest setfacl || error  "setfacl test failed"
11512
11513         # inheritance test got from HP
11514         echo "performing inheritance..."
11515         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11516         chmod +x make-tree || error "chmod +x failed"
11517         run_acl_subtest inheritance || error "inheritance test failed"
11518         rm -f make-tree
11519
11520         echo "LU-974 ignore umask when acl is enabled..."
11521         run_acl_subtest 974 || error "LU-974 umask test failed"
11522         if [ $MDSCOUNT -ge 2 ]; then
11523                 run_acl_subtest 974_remote ||
11524                         error "LU-974 umask test failed under remote dir"
11525         fi
11526
11527         echo "LU-2561 newly created file is same size as directory..."
11528         if [ "$mds1_FSTYPE" != "zfs" ]; then
11529                 run_acl_subtest 2561 || error "LU-2561 test failed"
11530         else
11531                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11532         fi
11533
11534         run_acl_subtest 4924 || error "LU-4924 test failed"
11535
11536         cd $SAVE_PWD
11537         umask $SAVE_UMASK
11538
11539         for num in $(seq $MDSCOUNT); do
11540                 if [ "${identity_old[$num]}" = 1 ]; then
11541                         switch_identity $num false || identity_old[$num]=$?
11542                 fi
11543         done
11544 }
11545 run_test 103a "acl test"
11546
11547 test_103b() {
11548         declare -a pids
11549         local U
11550
11551         for U in {0..511}; do
11552                 {
11553                 local O=$(printf "%04o" $U)
11554
11555                 umask $(printf "%04o" $((511 ^ $O)))
11556                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11557                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11558
11559                 (( $S == ($O & 0666) )) ||
11560                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11561
11562                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11563                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11564                 (( $S == ($O & 0666) )) ||
11565                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11566
11567                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11568                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11569                 (( $S == ($O & 0666) )) ||
11570                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11571                 rm -f $DIR/$tfile.[smp]$0
11572                 } &
11573                 local pid=$!
11574
11575                 # limit the concurrently running threads to 64. LU-11878
11576                 local idx=$((U % 64))
11577                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11578                 pids[idx]=$pid
11579         done
11580         wait
11581 }
11582 run_test 103b "umask lfs setstripe"
11583
11584 test_103c() {
11585         mkdir -p $DIR/$tdir
11586         cp -rp $DIR/$tdir $DIR/$tdir.bak
11587
11588         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11589                 error "$DIR/$tdir shouldn't contain default ACL"
11590         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11591                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11592         true
11593 }
11594 run_test 103c "'cp -rp' won't set empty acl"
11595
11596 test_103e() {
11597         local numacl
11598         local fileacl
11599         local saved_debug=$($LCTL get_param -n debug)
11600
11601         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11602                 skip "MDS needs to be at least 2.14.52"
11603
11604         large_xattr_enabled || skip_env "ea_inode feature disabled"
11605
11606         mkdir -p $DIR/$tdir
11607         # add big LOV EA to cause reply buffer overflow earlier
11608         $LFS setstripe -C 1000 $DIR/$tdir
11609         lctl set_param mdc.*-mdc*.stats=clear
11610
11611         $LCTL set_param debug=0
11612         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11613         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11614
11615         # add a large number of default ACLs (expect 8000+ for 2.13+)
11616         for U in {2..7000}; do
11617                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11618                         error "Able to add just $U default ACLs"
11619         done
11620         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11621         echo "$numacl default ACLs created"
11622
11623         stat $DIR/$tdir || error "Cannot stat directory"
11624         # check file creation
11625         touch $DIR/$tdir/$tfile ||
11626                 error "failed to create $tfile with $numacl default ACLs"
11627         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11628         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11629         echo "$fileacl ACLs were inherited"
11630         (( $fileacl == $numacl )) ||
11631                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11632         # check that new ACLs creation adds new ACLs to inherited ACLs
11633         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11634                 error "Cannot set new ACL"
11635         numacl=$((numacl + 1))
11636         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11637         (( $fileacl == $numacl )) ||
11638                 error "failed to add new ACL: $fileacl != $numacl as expected"
11639         # adds more ACLs to a file to reach their maximum at 8000+
11640         numacl=0
11641         for U in {20000..25000}; do
11642                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11643                 numacl=$((numacl + 1))
11644         done
11645         echo "Added $numacl more ACLs to the file"
11646         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11647         echo "Total $fileacl ACLs in file"
11648         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11649         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11650         rmdir $DIR/$tdir || error "Cannot remove directory"
11651 }
11652 run_test 103e "inheritance of big amount of default ACLs"
11653
11654 test_103f() {
11655         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11656                 skip "MDS needs to be at least 2.14.51"
11657
11658         large_xattr_enabled || skip_env "ea_inode feature disabled"
11659
11660         # enable changelog to consume more internal MDD buffers
11661         changelog_register
11662
11663         mkdir -p $DIR/$tdir
11664         # add big LOV EA
11665         $LFS setstripe -C 1000 $DIR/$tdir
11666         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11667         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11668         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11669         rmdir $DIR/$tdir || error "Cannot remove directory"
11670 }
11671 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11672
11673 test_104a() {
11674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11675
11676         touch $DIR/$tfile
11677         lfs df || error "lfs df failed"
11678         lfs df -ih || error "lfs df -ih failed"
11679         lfs df -h $DIR || error "lfs df -h $DIR failed"
11680         lfs df -i $DIR || error "lfs df -i $DIR failed"
11681         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11682         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11683
11684         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11685         lctl --device %$OSC deactivate
11686         lfs df || error "lfs df with deactivated OSC failed"
11687         lctl --device %$OSC activate
11688         # wait the osc back to normal
11689         wait_osc_import_ready client ost
11690
11691         lfs df || error "lfs df with reactivated OSC failed"
11692         rm -f $DIR/$tfile
11693 }
11694 run_test 104a "lfs df [-ih] [path] test ========================="
11695
11696 test_104b() {
11697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11698         [ $RUNAS_ID -eq $UID ] &&
11699                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11700
11701         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11702                         grep "Permission denied" | wc -l)))
11703         if [ $denied_cnt -ne 0 ]; then
11704                 error "lfs check servers test failed"
11705         fi
11706 }
11707 run_test 104b "$RUNAS lfs check servers test ===================="
11708
11709 #
11710 # Verify $1 is within range of $2.
11711 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11712 # $1 is <= 2% of $2. Else Fail.
11713 #
11714 value_in_range() {
11715         # Strip all units (M, G, T)
11716         actual=$(echo $1 | tr -d A-Z)
11717         expect=$(echo $2 | tr -d A-Z)
11718
11719         expect_lo=$(($expect * 98 / 100)) # 2% below
11720         expect_hi=$(($expect * 102 / 100)) # 2% above
11721
11722         # permit 2% drift above and below
11723         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11724 }
11725
11726 test_104c() {
11727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11728         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11729
11730         local ost_param="osd-zfs.$FSNAME-OST0000."
11731         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11732         local ofacets=$(get_facets OST)
11733         local mfacets=$(get_facets MDS)
11734         local saved_ost_blocks=
11735         local saved_mdt_blocks=
11736
11737         echo "Before recordsize change"
11738         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11739         df=($(df -h | grep "$MOUNT"$))
11740
11741         # For checking.
11742         echo "lfs output : ${lfs_df[*]}"
11743         echo "df  output : ${df[*]}"
11744
11745         for facet in ${ofacets//,/ }; do
11746                 if [ -z $saved_ost_blocks ]; then
11747                         saved_ost_blocks=$(do_facet $facet \
11748                                 lctl get_param -n $ost_param.blocksize)
11749                         echo "OST Blocksize: $saved_ost_blocks"
11750                 fi
11751                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11752                 do_facet $facet zfs set recordsize=32768 $ost
11753         done
11754
11755         # BS too small. Sufficient for functional testing.
11756         for facet in ${mfacets//,/ }; do
11757                 if [ -z $saved_mdt_blocks ]; then
11758                         saved_mdt_blocks=$(do_facet $facet \
11759                                 lctl get_param -n $mdt_param.blocksize)
11760                         echo "MDT Blocksize: $saved_mdt_blocks"
11761                 fi
11762                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11763                 do_facet $facet zfs set recordsize=32768 $mdt
11764         done
11765
11766         # Give new values chance to reflect change
11767         sleep 2
11768
11769         echo "After recordsize change"
11770         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11771         df_after=($(df -h | grep "$MOUNT"$))
11772
11773         # For checking.
11774         echo "lfs output : ${lfs_df_after[*]}"
11775         echo "df  output : ${df_after[*]}"
11776
11777         # Verify lfs df
11778         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11779                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11780         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11781                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11782         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11783                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11784
11785         # Verify df
11786         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11787                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11788         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11789                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11790         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11791                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11792
11793         # Restore MDT recordize back to original
11794         for facet in ${mfacets//,/ }; do
11795                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11796                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11797         done
11798
11799         # Restore OST recordize back to original
11800         for facet in ${ofacets//,/ }; do
11801                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11802                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11803         done
11804
11805         return 0
11806 }
11807 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11808
11809 test_105a() {
11810         # doesn't work on 2.4 kernels
11811         touch $DIR/$tfile
11812         if $(flock_is_enabled); then
11813                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11814         else
11815                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11816         fi
11817         rm -f $DIR/$tfile
11818 }
11819 run_test 105a "flock when mounted without -o flock test ========"
11820
11821 test_105b() {
11822         touch $DIR/$tfile
11823         if $(flock_is_enabled); then
11824                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11825         else
11826                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11827         fi
11828         rm -f $DIR/$tfile
11829 }
11830 run_test 105b "fcntl when mounted without -o flock test ========"
11831
11832 test_105c() {
11833         touch $DIR/$tfile
11834         if $(flock_is_enabled); then
11835                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11836         else
11837                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11838         fi
11839         rm -f $DIR/$tfile
11840 }
11841 run_test 105c "lockf when mounted without -o flock test"
11842
11843 test_105d() { # bug 15924
11844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11845
11846         test_mkdir $DIR/$tdir
11847         flock_is_enabled || skip_env "mount w/o flock enabled"
11848         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11849         $LCTL set_param fail_loc=0x80000315
11850         flocks_test 2 $DIR/$tdir
11851 }
11852 run_test 105d "flock race (should not freeze) ========"
11853
11854 test_105e() { # bug 22660 && 22040
11855         flock_is_enabled || skip_env "mount w/o flock enabled"
11856
11857         touch $DIR/$tfile
11858         flocks_test 3 $DIR/$tfile
11859 }
11860 run_test 105e "Two conflicting flocks from same process"
11861
11862 test_106() { #bug 10921
11863         test_mkdir $DIR/$tdir
11864         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11865         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11866 }
11867 run_test 106 "attempt exec of dir followed by chown of that dir"
11868
11869 test_107() {
11870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11871
11872         CDIR=`pwd`
11873         local file=core
11874
11875         cd $DIR
11876         rm -f $file
11877
11878         local save_pattern=$(sysctl -n kernel.core_pattern)
11879         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11880         sysctl -w kernel.core_pattern=$file
11881         sysctl -w kernel.core_uses_pid=0
11882
11883         ulimit -c unlimited
11884         sleep 60 &
11885         SLEEPPID=$!
11886
11887         sleep 1
11888
11889         kill -s 11 $SLEEPPID
11890         wait $SLEEPPID
11891         if [ -e $file ]; then
11892                 size=`stat -c%s $file`
11893                 [ $size -eq 0 ] && error "Fail to create core file $file"
11894         else
11895                 error "Fail to create core file $file"
11896         fi
11897         rm -f $file
11898         sysctl -w kernel.core_pattern=$save_pattern
11899         sysctl -w kernel.core_uses_pid=$save_uses_pid
11900         cd $CDIR
11901 }
11902 run_test 107 "Coredump on SIG"
11903
11904 test_110() {
11905         test_mkdir $DIR/$tdir
11906         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11907         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11908                 error "mkdir with 256 char should fail, but did not"
11909         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11910                 error "create with 255 char failed"
11911         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11912                 error "create with 256 char should fail, but did not"
11913
11914         ls -l $DIR/$tdir
11915         rm -rf $DIR/$tdir
11916 }
11917 run_test 110 "filename length checking"
11918
11919 #
11920 # Purpose: To verify dynamic thread (OSS) creation.
11921 #
11922 test_115() {
11923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11924         remote_ost_nodsh && skip "remote OST with nodsh"
11925
11926         # Lustre does not stop service threads once they are started.
11927         # Reset number of running threads to default.
11928         stopall
11929         setupall
11930
11931         local OSTIO_pre
11932         local save_params="$TMP/sanity-$TESTNAME.parameters"
11933
11934         # Get ll_ost_io count before I/O
11935         OSTIO_pre=$(do_facet ost1 \
11936                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11937         # Exit if lustre is not running (ll_ost_io not running).
11938         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11939
11940         echo "Starting with $OSTIO_pre threads"
11941         local thread_max=$((OSTIO_pre * 2))
11942         local rpc_in_flight=$((thread_max * 2))
11943         # this is limited to OSC_MAX_RIF_MAX (256)
11944         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11945         thread_max=$((rpc_in_flight / 2))
11946         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11947                 return
11948
11949         # Number of I/O Process proposed to be started.
11950         local nfiles
11951         local facets=$(get_facets OST)
11952
11953         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11954         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11955
11956         # Set in_flight to $rpc_in_flight
11957         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11958                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11959         nfiles=${rpc_in_flight}
11960         # Set ost thread_max to $thread_max
11961         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11962
11963         # 5 Minutes should be sufficient for max number of OSS
11964         # threads(thread_max) to be created.
11965         local timeout=300
11966
11967         # Start I/O.
11968         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11969         test_mkdir $DIR/$tdir
11970         for i in $(seq $nfiles); do
11971                 local file=$DIR/$tdir/${tfile}-$i
11972                 $LFS setstripe -c -1 -i 0 $file
11973                 ($WTL $file $timeout)&
11974         done
11975
11976         # I/O Started - Wait for thread_started to reach thread_max or report
11977         # error if thread_started is more than thread_max.
11978         echo "Waiting for thread_started to reach thread_max"
11979         local thread_started=0
11980         local end_time=$((SECONDS + timeout))
11981
11982         while [ $SECONDS -le $end_time ] ; do
11983                 echo -n "."
11984                 # Get ost i/o thread_started count.
11985                 thread_started=$(do_facet ost1 \
11986                         "$LCTL get_param \
11987                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11988                 # Break out if thread_started is equal/greater than thread_max
11989                 if [[ $thread_started -ge $thread_max ]]; then
11990                         echo ll_ost_io thread_started $thread_started, \
11991                                 equal/greater than thread_max $thread_max
11992                         break
11993                 fi
11994                 sleep 1
11995         done
11996
11997         # Cleanup - We have the numbers, Kill i/o jobs if running.
11998         jobcount=($(jobs -p))
11999         for i in $(seq 0 $((${#jobcount[@]}-1)))
12000         do
12001                 kill -9 ${jobcount[$i]}
12002                 if [ $? -ne 0 ] ; then
12003                         echo Warning: \
12004                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
12005                 fi
12006         done
12007
12008         # Cleanup files left by WTL binary.
12009         for i in $(seq $nfiles); do
12010                 local file=$DIR/$tdir/${tfile}-$i
12011                 rm -rf $file
12012                 if [ $? -ne 0 ] ; then
12013                         echo "Warning: Failed to delete file $file"
12014                 fi
12015         done
12016
12017         restore_lustre_params <$save_params
12018         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
12019
12020         # Error out if no new thread has started or Thread started is greater
12021         # than thread max.
12022         if [[ $thread_started -le $OSTIO_pre ||
12023                         $thread_started -gt $thread_max ]]; then
12024                 error "ll_ost_io: thread_started $thread_started" \
12025                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
12026                       "No new thread started or thread started greater " \
12027                       "than thread_max."
12028         fi
12029 }
12030 run_test 115 "verify dynamic thread creation===================="
12031
12032 test_116a() { # was previously test_116()
12033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12034         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12035         remote_mds_nodsh && skip "remote MDS with nodsh"
12036
12037         echo -n "Free space priority "
12038         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12039                 head -n1
12040         declare -a AVAIL
12041         free_min_max
12042
12043         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12044         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12045         stack_trap simple_cleanup_common
12046
12047         # Check if we need to generate uneven OSTs
12048         test_mkdir -p $DIR/$tdir/OST${MINI}
12049         local FILL=$((MINV / 4))
12050         local DIFF=$((MAXV - MINV))
12051         local DIFF2=$((DIFF * 100 / MINV))
12052
12053         local threshold=$(do_facet $SINGLEMDS \
12054                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12055         threshold=${threshold%%%}
12056         echo -n "Check for uneven OSTs: "
12057         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12058
12059         if [[ $DIFF2 -gt $threshold ]]; then
12060                 echo "ok"
12061                 echo "Don't need to fill OST$MINI"
12062         else
12063                 # generate uneven OSTs. Write 2% over the QOS threshold value
12064                 echo "no"
12065                 DIFF=$((threshold - DIFF2 + 2))
12066                 DIFF2=$((MINV * DIFF / 100))
12067                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12068                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12069                         error "setstripe failed"
12070                 DIFF=$((DIFF2 / 2048))
12071                 i=0
12072                 while [ $i -lt $DIFF ]; do
12073                         i=$((i + 1))
12074                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12075                                 bs=2M count=1 2>/dev/null
12076                         echo -n .
12077                 done
12078                 echo .
12079                 sync
12080                 sleep_maxage
12081                 free_min_max
12082         fi
12083
12084         DIFF=$((MAXV - MINV))
12085         DIFF2=$((DIFF * 100 / MINV))
12086         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12087         if [ $DIFF2 -gt $threshold ]; then
12088                 echo "ok"
12089         else
12090                 skip "QOS imbalance criteria not met"
12091         fi
12092
12093         MINI1=$MINI
12094         MINV1=$MINV
12095         MAXI1=$MAXI
12096         MAXV1=$MAXV
12097
12098         # now fill using QOS
12099         $LFS setstripe -c 1 $DIR/$tdir
12100         FILL=$((FILL / 200))
12101         if [ $FILL -gt 600 ]; then
12102                 FILL=600
12103         fi
12104         echo "writing $FILL files to QOS-assigned OSTs"
12105         i=0
12106         while [ $i -lt $FILL ]; do
12107                 i=$((i + 1))
12108                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12109                         count=1 2>/dev/null
12110                 echo -n .
12111         done
12112         echo "wrote $i 200k files"
12113         sync
12114         sleep_maxage
12115
12116         echo "Note: free space may not be updated, so measurements might be off"
12117         free_min_max
12118         DIFF2=$((MAXV - MINV))
12119         echo "free space delta: orig $DIFF final $DIFF2"
12120         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12121         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12122         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12123         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12124         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12125         if [[ $DIFF -gt 0 ]]; then
12126                 FILL=$((DIFF2 * 100 / DIFF - 100))
12127                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12128         fi
12129
12130         # Figure out which files were written where
12131         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12132                awk '/'$MINI1': / {print $2; exit}')
12133         echo $UUID
12134         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12135         echo "$MINC files created on smaller OST $MINI1"
12136         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12137                awk '/'$MAXI1': / {print $2; exit}')
12138         echo $UUID
12139         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12140         echo "$MAXC files created on larger OST $MAXI1"
12141         if [[ $MINC -gt 0 ]]; then
12142                 FILL=$((MAXC * 100 / MINC - 100))
12143                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12144         fi
12145         [[ $MAXC -gt $MINC ]] ||
12146                 error_ignore LU-9 "stripe QOS didn't balance free space"
12147 }
12148 run_test 116a "stripe QOS: free space balance ==================="
12149
12150 test_116b() { # LU-2093
12151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12152         remote_mds_nodsh && skip "remote MDS with nodsh"
12153
12154 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12155         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12156                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12157         [ -z "$old_rr" ] && skip "no QOS"
12158         do_facet $SINGLEMDS lctl set_param \
12159                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12160         mkdir -p $DIR/$tdir
12161         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12162         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12163         do_facet $SINGLEMDS lctl set_param fail_loc=0
12164         rm -rf $DIR/$tdir
12165         do_facet $SINGLEMDS lctl set_param \
12166                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12167 }
12168 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12169
12170 test_117() # bug 10891
12171 {
12172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12173
12174         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12175         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12176         lctl set_param fail_loc=0x21e
12177         > $DIR/$tfile || error "truncate failed"
12178         lctl set_param fail_loc=0
12179         echo "Truncate succeeded."
12180         rm -f $DIR/$tfile
12181 }
12182 run_test 117 "verify osd extend =========="
12183
12184 NO_SLOW_RESENDCOUNT=4
12185 export OLD_RESENDCOUNT=""
12186 set_resend_count () {
12187         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12188         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12189         lctl set_param -n $PROC_RESENDCOUNT $1
12190         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12191 }
12192
12193 # for reduce test_118* time (b=14842)
12194 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12195
12196 # Reset async IO behavior after error case
12197 reset_async() {
12198         FILE=$DIR/reset_async
12199
12200         # Ensure all OSCs are cleared
12201         $LFS setstripe -c -1 $FILE
12202         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12203         sync
12204         rm $FILE
12205 }
12206
12207 test_118a() #bug 11710
12208 {
12209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12210
12211         reset_async
12212
12213         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12214         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12215         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12216
12217         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12218                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12219                 return 1;
12220         fi
12221         rm -f $DIR/$tfile
12222 }
12223 run_test 118a "verify O_SYNC works =========="
12224
12225 test_118b()
12226 {
12227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12228         remote_ost_nodsh && skip "remote OST with nodsh"
12229
12230         reset_async
12231
12232         #define OBD_FAIL_SRV_ENOENT 0x217
12233         set_nodes_failloc "$(osts_nodes)" 0x217
12234         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12235         RC=$?
12236         set_nodes_failloc "$(osts_nodes)" 0
12237         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12238         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12239                     grep -c writeback)
12240
12241         if [[ $RC -eq 0 ]]; then
12242                 error "Must return error due to dropped pages, rc=$RC"
12243                 return 1;
12244         fi
12245
12246         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12247                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12248                 return 1;
12249         fi
12250
12251         echo "Dirty pages not leaked on ENOENT"
12252
12253         # Due to the above error the OSC will issue all RPCs syncronously
12254         # until a subsequent RPC completes successfully without error.
12255         $MULTIOP $DIR/$tfile Ow4096yc
12256         rm -f $DIR/$tfile
12257
12258         return 0
12259 }
12260 run_test 118b "Reclaim dirty pages on fatal error =========="
12261
12262 test_118c()
12263 {
12264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12265
12266         # for 118c, restore the original resend count, LU-1940
12267         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12268                                 set_resend_count $OLD_RESENDCOUNT
12269         remote_ost_nodsh && skip "remote OST with nodsh"
12270
12271         reset_async
12272
12273         #define OBD_FAIL_OST_EROFS               0x216
12274         set_nodes_failloc "$(osts_nodes)" 0x216
12275
12276         # multiop should block due to fsync until pages are written
12277         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12278         MULTIPID=$!
12279         sleep 1
12280
12281         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12282                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12283         fi
12284
12285         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12286                     grep -c writeback)
12287         if [[ $WRITEBACK -eq 0 ]]; then
12288                 error "No page in writeback, writeback=$WRITEBACK"
12289         fi
12290
12291         set_nodes_failloc "$(osts_nodes)" 0
12292         wait $MULTIPID
12293         RC=$?
12294         if [[ $RC -ne 0 ]]; then
12295                 error "Multiop fsync failed, rc=$RC"
12296         fi
12297
12298         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12299         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12300                     grep -c writeback)
12301         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12302                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12303         fi
12304
12305         rm -f $DIR/$tfile
12306         echo "Dirty pages flushed via fsync on EROFS"
12307         return 0
12308 }
12309 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12310
12311 # continue to use small resend count to reduce test_118* time (b=14842)
12312 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12313
12314 test_118d()
12315 {
12316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12317         remote_ost_nodsh && skip "remote OST with nodsh"
12318
12319         reset_async
12320
12321         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12322         set_nodes_failloc "$(osts_nodes)" 0x214
12323         # multiop should block due to fsync until pages are written
12324         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12325         MULTIPID=$!
12326         sleep 1
12327
12328         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12329                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12330         fi
12331
12332         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12333                     grep -c writeback)
12334         if [[ $WRITEBACK -eq 0 ]]; then
12335                 error "No page in writeback, writeback=$WRITEBACK"
12336         fi
12337
12338         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12339         set_nodes_failloc "$(osts_nodes)" 0
12340
12341         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12342         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12343                     grep -c writeback)
12344         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12345                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12346         fi
12347
12348         rm -f $DIR/$tfile
12349         echo "Dirty pages gaurenteed flushed via fsync"
12350         return 0
12351 }
12352 run_test 118d "Fsync validation inject a delay of the bulk =========="
12353
12354 test_118f() {
12355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12356
12357         reset_async
12358
12359         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12360         lctl set_param fail_loc=0x8000040a
12361
12362         # Should simulate EINVAL error which is fatal
12363         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12364         RC=$?
12365         if [[ $RC -eq 0 ]]; then
12366                 error "Must return error due to dropped pages, rc=$RC"
12367         fi
12368
12369         lctl set_param fail_loc=0x0
12370
12371         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12372         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12373         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12374                     grep -c writeback)
12375         if [[ $LOCKED -ne 0 ]]; then
12376                 error "Locked pages remain in cache, locked=$LOCKED"
12377         fi
12378
12379         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12380                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12381         fi
12382
12383         rm -f $DIR/$tfile
12384         echo "No pages locked after fsync"
12385
12386         reset_async
12387         return 0
12388 }
12389 run_test 118f "Simulate unrecoverable OSC side error =========="
12390
12391 test_118g() {
12392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12393
12394         reset_async
12395
12396         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12397         lctl set_param fail_loc=0x406
12398
12399         # simulate local -ENOMEM
12400         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12401         RC=$?
12402
12403         lctl set_param fail_loc=0
12404         if [[ $RC -eq 0 ]]; then
12405                 error "Must return error due to dropped pages, rc=$RC"
12406         fi
12407
12408         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12409         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12410         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12411                         grep -c writeback)
12412         if [[ $LOCKED -ne 0 ]]; then
12413                 error "Locked pages remain in cache, locked=$LOCKED"
12414         fi
12415
12416         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12417                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12418         fi
12419
12420         rm -f $DIR/$tfile
12421         echo "No pages locked after fsync"
12422
12423         reset_async
12424         return 0
12425 }
12426 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12427
12428 test_118h() {
12429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12430         remote_ost_nodsh && skip "remote OST with nodsh"
12431
12432         reset_async
12433
12434         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12435         set_nodes_failloc "$(osts_nodes)" 0x20e
12436         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12437         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12438         RC=$?
12439
12440         set_nodes_failloc "$(osts_nodes)" 0
12441         if [[ $RC -eq 0 ]]; then
12442                 error "Must return error due to dropped pages, rc=$RC"
12443         fi
12444
12445         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12446         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12447         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12448                     grep -c writeback)
12449         if [[ $LOCKED -ne 0 ]]; then
12450                 error "Locked pages remain in cache, locked=$LOCKED"
12451         fi
12452
12453         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12454                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12455         fi
12456
12457         rm -f $DIR/$tfile
12458         echo "No pages locked after fsync"
12459
12460         return 0
12461 }
12462 run_test 118h "Verify timeout in handling recoverables errors  =========="
12463
12464 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12465
12466 test_118i() {
12467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12468         remote_ost_nodsh && skip "remote OST with nodsh"
12469
12470         reset_async
12471
12472         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12473         set_nodes_failloc "$(osts_nodes)" 0x20e
12474
12475         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12476         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12477         PID=$!
12478         sleep 5
12479         set_nodes_failloc "$(osts_nodes)" 0
12480
12481         wait $PID
12482         RC=$?
12483         if [[ $RC -ne 0 ]]; then
12484                 error "got error, but should be not, rc=$RC"
12485         fi
12486
12487         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12488         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12489         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12490         if [[ $LOCKED -ne 0 ]]; then
12491                 error "Locked pages remain in cache, locked=$LOCKED"
12492         fi
12493
12494         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12495                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12496         fi
12497
12498         rm -f $DIR/$tfile
12499         echo "No pages locked after fsync"
12500
12501         return 0
12502 }
12503 run_test 118i "Fix error before timeout in recoverable error  =========="
12504
12505 [ "$SLOW" = "no" ] && set_resend_count 4
12506
12507 test_118j() {
12508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12509         remote_ost_nodsh && skip "remote OST with nodsh"
12510
12511         reset_async
12512
12513         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12514         set_nodes_failloc "$(osts_nodes)" 0x220
12515
12516         # return -EIO from OST
12517         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12518         RC=$?
12519         set_nodes_failloc "$(osts_nodes)" 0x0
12520         if [[ $RC -eq 0 ]]; then
12521                 error "Must return error due to dropped pages, rc=$RC"
12522         fi
12523
12524         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12525         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12526         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12527         if [[ $LOCKED -ne 0 ]]; then
12528                 error "Locked pages remain in cache, locked=$LOCKED"
12529         fi
12530
12531         # in recoverable error on OST we want resend and stay until it finished
12532         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12533                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12534         fi
12535
12536         rm -f $DIR/$tfile
12537         echo "No pages locked after fsync"
12538
12539         return 0
12540 }
12541 run_test 118j "Simulate unrecoverable OST side error =========="
12542
12543 test_118k()
12544 {
12545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12546         remote_ost_nodsh && skip "remote OSTs with nodsh"
12547
12548         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12549         set_nodes_failloc "$(osts_nodes)" 0x20e
12550         test_mkdir $DIR/$tdir
12551
12552         for ((i=0;i<10;i++)); do
12553                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12554                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12555                 SLEEPPID=$!
12556                 sleep 0.500s
12557                 kill $SLEEPPID
12558                 wait $SLEEPPID
12559         done
12560
12561         set_nodes_failloc "$(osts_nodes)" 0
12562         rm -rf $DIR/$tdir
12563 }
12564 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12565
12566 test_118l() # LU-646
12567 {
12568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12569
12570         test_mkdir $DIR/$tdir
12571         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12572         rm -rf $DIR/$tdir
12573 }
12574 run_test 118l "fsync dir"
12575
12576 test_118m() # LU-3066
12577 {
12578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12579
12580         test_mkdir $DIR/$tdir
12581         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12582         rm -rf $DIR/$tdir
12583 }
12584 run_test 118m "fdatasync dir ========="
12585
12586 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12587
12588 test_118n()
12589 {
12590         local begin
12591         local end
12592
12593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12594         remote_ost_nodsh && skip "remote OSTs with nodsh"
12595
12596         # Sleep to avoid a cached response.
12597         #define OBD_STATFS_CACHE_SECONDS 1
12598         sleep 2
12599
12600         # Inject a 10 second delay in the OST_STATFS handler.
12601         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12602         set_nodes_failloc "$(osts_nodes)" 0x242
12603
12604         begin=$SECONDS
12605         stat --file-system $MOUNT > /dev/null
12606         end=$SECONDS
12607
12608         set_nodes_failloc "$(osts_nodes)" 0
12609
12610         if ((end - begin > 20)); then
12611             error "statfs took $((end - begin)) seconds, expected 10"
12612         fi
12613 }
12614 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12615
12616 test_119a() # bug 11737
12617 {
12618         BSIZE=$((512 * 1024))
12619         directio write $DIR/$tfile 0 1 $BSIZE
12620         # We ask to read two blocks, which is more than a file size.
12621         # directio will indicate an error when requested and actual
12622         # sizes aren't equeal (a normal situation in this case) and
12623         # print actual read amount.
12624         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12625         if [ "$NOB" != "$BSIZE" ]; then
12626                 error "read $NOB bytes instead of $BSIZE"
12627         fi
12628         rm -f $DIR/$tfile
12629 }
12630 run_test 119a "Short directIO read must return actual read amount"
12631
12632 test_119b() # bug 11737
12633 {
12634         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12635
12636         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12637         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12638         sync
12639         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12640                 error "direct read failed"
12641         rm -f $DIR/$tfile
12642 }
12643 run_test 119b "Sparse directIO read must return actual read amount"
12644
12645 test_119c() # bug 13099
12646 {
12647         BSIZE=1048576
12648         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12649         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12650         rm -f $DIR/$tfile
12651 }
12652 run_test 119c "Testing for direct read hitting hole"
12653
12654 test_119d() # bug 15950
12655 {
12656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12657
12658         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12659         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12660         BSIZE=1048576
12661         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12662         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12663         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12664         lctl set_param fail_loc=0x40d
12665         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12666         pid_dio=$!
12667         sleep 1
12668         cat $DIR/$tfile > /dev/null &
12669         lctl set_param fail_loc=0
12670         pid_reads=$!
12671         wait $pid_dio
12672         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12673         sleep 2
12674         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12675         error "the read rpcs have not completed in 2s"
12676         rm -f $DIR/$tfile
12677         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12678 }
12679 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12680
12681 test_120a() {
12682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12683         remote_mds_nodsh && skip "remote MDS with nodsh"
12684         test_mkdir -i0 -c1 $DIR/$tdir
12685         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12686                 skip_env "no early lock cancel on server"
12687
12688         lru_resize_disable mdc
12689         lru_resize_disable osc
12690         cancel_lru_locks mdc
12691         # asynchronous object destroy at MDT could cause bl ast to client
12692         cancel_lru_locks osc
12693
12694         stat $DIR/$tdir > /dev/null
12695         can1=$(do_facet mds1 \
12696                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12697                awk '/ldlm_cancel/ {print $2}')
12698         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12699                awk '/ldlm_bl_callback/ {print $2}')
12700         test_mkdir -i0 -c1 $DIR/$tdir/d1
12701         can2=$(do_facet mds1 \
12702                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12703                awk '/ldlm_cancel/ {print $2}')
12704         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12705                awk '/ldlm_bl_callback/ {print $2}')
12706         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12707         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12708         lru_resize_enable mdc
12709         lru_resize_enable osc
12710 }
12711 run_test 120a "Early Lock Cancel: mkdir test"
12712
12713 test_120b() {
12714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12715         remote_mds_nodsh && skip "remote MDS with nodsh"
12716         test_mkdir $DIR/$tdir
12717         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12718                 skip_env "no early lock cancel on server"
12719
12720         lru_resize_disable mdc
12721         lru_resize_disable osc
12722         cancel_lru_locks mdc
12723         stat $DIR/$tdir > /dev/null
12724         can1=$(do_facet $SINGLEMDS \
12725                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12726                awk '/ldlm_cancel/ {print $2}')
12727         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12728                awk '/ldlm_bl_callback/ {print $2}')
12729         touch $DIR/$tdir/f1
12730         can2=$(do_facet $SINGLEMDS \
12731                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12732                awk '/ldlm_cancel/ {print $2}')
12733         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12734                awk '/ldlm_bl_callback/ {print $2}')
12735         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12736         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12737         lru_resize_enable mdc
12738         lru_resize_enable osc
12739 }
12740 run_test 120b "Early Lock Cancel: create test"
12741
12742 test_120c() {
12743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12744         remote_mds_nodsh && skip "remote MDS with nodsh"
12745         test_mkdir -i0 -c1 $DIR/$tdir
12746         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12747                 skip "no early lock cancel on server"
12748
12749         lru_resize_disable mdc
12750         lru_resize_disable osc
12751         test_mkdir -i0 -c1 $DIR/$tdir/d1
12752         test_mkdir -i0 -c1 $DIR/$tdir/d2
12753         touch $DIR/$tdir/d1/f1
12754         cancel_lru_locks mdc
12755         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12756         can1=$(do_facet mds1 \
12757                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12758                awk '/ldlm_cancel/ {print $2}')
12759         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12760                awk '/ldlm_bl_callback/ {print $2}')
12761         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12762         can2=$(do_facet mds1 \
12763                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12764                awk '/ldlm_cancel/ {print $2}')
12765         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12766                awk '/ldlm_bl_callback/ {print $2}')
12767         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12768         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12769         lru_resize_enable mdc
12770         lru_resize_enable osc
12771 }
12772 run_test 120c "Early Lock Cancel: link test"
12773
12774 test_120d() {
12775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12776         remote_mds_nodsh && skip "remote MDS with nodsh"
12777         test_mkdir -i0 -c1 $DIR/$tdir
12778         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12779                 skip_env "no early lock cancel on server"
12780
12781         lru_resize_disable mdc
12782         lru_resize_disable osc
12783         touch $DIR/$tdir
12784         cancel_lru_locks mdc
12785         stat $DIR/$tdir > /dev/null
12786         can1=$(do_facet mds1 \
12787                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12788                awk '/ldlm_cancel/ {print $2}')
12789         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12790                awk '/ldlm_bl_callback/ {print $2}')
12791         chmod a+x $DIR/$tdir
12792         can2=$(do_facet mds1 \
12793                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12794                awk '/ldlm_cancel/ {print $2}')
12795         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12796                awk '/ldlm_bl_callback/ {print $2}')
12797         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12798         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12799         lru_resize_enable mdc
12800         lru_resize_enable osc
12801 }
12802 run_test 120d "Early Lock Cancel: setattr test"
12803
12804 test_120e() {
12805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12806         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12807                 skip_env "no early lock cancel on server"
12808         remote_mds_nodsh && skip "remote MDS with nodsh"
12809
12810         local dlmtrace_set=false
12811
12812         test_mkdir -i0 -c1 $DIR/$tdir
12813         lru_resize_disable mdc
12814         lru_resize_disable osc
12815         ! $LCTL get_param debug | grep -q dlmtrace &&
12816                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12817         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12818         cancel_lru_locks mdc
12819         cancel_lru_locks osc
12820         dd if=$DIR/$tdir/f1 of=/dev/null
12821         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12822         # XXX client can not do early lock cancel of OST lock
12823         # during unlink (LU-4206), so cancel osc lock now.
12824         sleep 2
12825         cancel_lru_locks osc
12826         can1=$(do_facet mds1 \
12827                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12828                awk '/ldlm_cancel/ {print $2}')
12829         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12830                awk '/ldlm_bl_callback/ {print $2}')
12831         unlink $DIR/$tdir/f1
12832         sleep 5
12833         can2=$(do_facet mds1 \
12834                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12835                awk '/ldlm_cancel/ {print $2}')
12836         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12837                awk '/ldlm_bl_callback/ {print $2}')
12838         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12839                 $LCTL dk $TMP/cancel.debug.txt
12840         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12841                 $LCTL dk $TMP/blocking.debug.txt
12842         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12843         lru_resize_enable mdc
12844         lru_resize_enable osc
12845 }
12846 run_test 120e "Early Lock Cancel: unlink test"
12847
12848 test_120f() {
12849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12850         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12851                 skip_env "no early lock cancel on server"
12852         remote_mds_nodsh && skip "remote MDS with nodsh"
12853
12854         test_mkdir -i0 -c1 $DIR/$tdir
12855         lru_resize_disable mdc
12856         lru_resize_disable osc
12857         test_mkdir -i0 -c1 $DIR/$tdir/d1
12858         test_mkdir -i0 -c1 $DIR/$tdir/d2
12859         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12860         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12861         cancel_lru_locks mdc
12862         cancel_lru_locks osc
12863         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12864         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12865         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12866         # XXX client can not do early lock cancel of OST lock
12867         # during rename (LU-4206), so cancel osc lock now.
12868         sleep 2
12869         cancel_lru_locks osc
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         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12876         sleep 5
12877         can2=$(do_facet mds1 \
12878                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12879                awk '/ldlm_cancel/ {print $2}')
12880         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12881                awk '/ldlm_bl_callback/ {print $2}')
12882         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12883         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12884         lru_resize_enable mdc
12885         lru_resize_enable osc
12886 }
12887 run_test 120f "Early Lock Cancel: rename test"
12888
12889 test_120g() {
12890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12891         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12892                 skip_env "no early lock cancel on server"
12893         remote_mds_nodsh && skip "remote MDS with nodsh"
12894
12895         lru_resize_disable mdc
12896         lru_resize_disable osc
12897         count=10000
12898         echo create $count files
12899         test_mkdir $DIR/$tdir
12900         cancel_lru_locks mdc
12901         cancel_lru_locks osc
12902         t0=$(date +%s)
12903
12904         can0=$(do_facet $SINGLEMDS \
12905                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12906                awk '/ldlm_cancel/ {print $2}')
12907         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12908                awk '/ldlm_bl_callback/ {print $2}')
12909         createmany -o $DIR/$tdir/f $count
12910         sync
12911         can1=$(do_facet $SINGLEMDS \
12912                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12913                awk '/ldlm_cancel/ {print $2}')
12914         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12915                awk '/ldlm_bl_callback/ {print $2}')
12916         t1=$(date +%s)
12917         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12918         echo rm $count files
12919         rm -r $DIR/$tdir
12920         sync
12921         can2=$(do_facet $SINGLEMDS \
12922                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12923                awk '/ldlm_cancel/ {print $2}')
12924         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12925                awk '/ldlm_bl_callback/ {print $2}')
12926         t2=$(date +%s)
12927         echo total: $count removes in $((t2-t1))
12928         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12929         sleep 2
12930         # wait for commitment of removal
12931         lru_resize_enable mdc
12932         lru_resize_enable osc
12933 }
12934 run_test 120g "Early Lock Cancel: performance test"
12935
12936 test_121() { #bug #10589
12937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12938
12939         rm -rf $DIR/$tfile
12940         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12941 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12942         lctl set_param fail_loc=0x310
12943         cancel_lru_locks osc > /dev/null
12944         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12945         lctl set_param fail_loc=0
12946         [[ $reads -eq $writes ]] ||
12947                 error "read $reads blocks, must be $writes blocks"
12948 }
12949 run_test 121 "read cancel race ========="
12950
12951 test_123a_base() { # was test 123, statahead(bug 11401)
12952         local lsx="$1"
12953
12954         SLOWOK=0
12955         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12956                 log "testing UP system. Performance may be lower than expected."
12957                 SLOWOK=1
12958         fi
12959         running_in_vm && SLOWOK=1
12960
12961         rm -rf $DIR/$tdir
12962         test_mkdir $DIR/$tdir
12963         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12964         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12965         MULT=10
12966         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12967                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12968
12969                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12970                 lctl set_param -n llite.*.statahead_max 0
12971                 lctl get_param llite.*.statahead_max
12972                 cancel_lru_locks mdc
12973                 cancel_lru_locks osc
12974                 stime=$(date +%s)
12975                 time $lsx $DIR/$tdir | wc -l
12976                 etime=$(date +%s)
12977                 delta=$((etime - stime))
12978                 log "$lsx $i files without statahead: $delta sec"
12979                 lctl set_param llite.*.statahead_max=$max
12980
12981                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12982                         grep "statahead wrong:" | awk '{print $3}')
12983                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12984                 cancel_lru_locks mdc
12985                 cancel_lru_locks osc
12986                 stime=$(date +%s)
12987                 time $lsx $DIR/$tdir | wc -l
12988                 etime=$(date +%s)
12989                 delta_sa=$((etime - stime))
12990                 log "$lsx $i files with statahead: $delta_sa sec"
12991                 lctl get_param -n llite.*.statahead_stats
12992                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12993                         grep "statahead wrong:" | awk '{print $3}')
12994
12995                 [[ $swrong -lt $ewrong ]] &&
12996                         log "statahead was stopped, maybe too many locks held!"
12997                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12998
12999                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
13000                         max=$(lctl get_param -n llite.*.statahead_max |
13001                                 head -n 1)
13002                         lctl set_param -n llite.*.statahead_max 0
13003                         lctl get_param llite.*.statahead_max
13004                         cancel_lru_locks mdc
13005                         cancel_lru_locks osc
13006                         stime=$(date +%s)
13007                         time $lsx $DIR/$tdir | wc -l
13008                         etime=$(date +%s)
13009                         delta=$((etime - stime))
13010                         log "$lsx $i files again without statahead: $delta sec"
13011                         lctl set_param llite.*.statahead_max=$max
13012                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
13013                                 if [  $SLOWOK -eq 0 ]; then
13014                                         error "$lsx $i files is slower with statahead!"
13015                                 else
13016                                         log "$lsx $i files is slower with statahead!"
13017                                 fi
13018                                 break
13019                         fi
13020                 fi
13021
13022                 [ $delta -gt 20 ] && break
13023                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13024                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13025         done
13026         log "$lsx done"
13027
13028         stime=$(date +%s)
13029         rm -r $DIR/$tdir
13030         sync
13031         etime=$(date +%s)
13032         delta=$((etime - stime))
13033         log "rm -r $DIR/$tdir/: $delta seconds"
13034         log "rm done"
13035         lctl get_param -n llite.*.statahead_stats
13036 }
13037
13038 test_123aa() {
13039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13040
13041         test_123a_base "ls -l"
13042 }
13043 run_test 123aa "verify statahead work"
13044
13045 test_123ab() {
13046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13047
13048         statx_supported || skip_env "Test must be statx() syscall supported"
13049
13050         test_123a_base "$STATX -l"
13051 }
13052 run_test 123ab "verify statahead work by using statx"
13053
13054 test_123ac() {
13055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13056
13057         statx_supported || skip_env "Test must be statx() syscall supported"
13058
13059         local rpcs_before
13060         local rpcs_after
13061         local agl_before
13062         local agl_after
13063
13064         cancel_lru_locks $OSC
13065         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13066         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13067                 awk '/agl.total:/ {print $3}')
13068         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13069         test_123a_base "$STATX --cached=always -D"
13070         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13071                 awk '/agl.total:/ {print $3}')
13072         [ $agl_before -eq $agl_after ] ||
13073                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13074         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13075         [ $rpcs_after -eq $rpcs_before ] ||
13076                 error "$STATX should not send glimpse RPCs to $OSC"
13077 }
13078 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13079
13080 test_123b () { # statahead(bug 15027)
13081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13082
13083         test_mkdir $DIR/$tdir
13084         createmany -o $DIR/$tdir/$tfile-%d 1000
13085
13086         cancel_lru_locks mdc
13087         cancel_lru_locks osc
13088
13089 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13090         lctl set_param fail_loc=0x80000803
13091         ls -lR $DIR/$tdir > /dev/null
13092         log "ls done"
13093         lctl set_param fail_loc=0x0
13094         lctl get_param -n llite.*.statahead_stats
13095         rm -r $DIR/$tdir
13096         sync
13097
13098 }
13099 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13100
13101 test_123c() {
13102         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13103
13104         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13105         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13106         touch $DIR/$tdir.1/{1..3}
13107         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13108
13109         remount_client $MOUNT
13110
13111         $MULTIOP $DIR/$tdir.0 Q
13112
13113         # let statahead to complete
13114         ls -l $DIR/$tdir.0 > /dev/null
13115
13116         testid=$(echo $TESTNAME | tr '_' ' ')
13117         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13118                 error "statahead warning" || true
13119 }
13120 run_test 123c "Can not initialize inode warning on DNE statahead"
13121
13122 test_124a() {
13123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13124         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13125                 skip_env "no lru resize on server"
13126
13127         local NR=2000
13128
13129         test_mkdir $DIR/$tdir
13130
13131         log "create $NR files at $DIR/$tdir"
13132         createmany -o $DIR/$tdir/f $NR ||
13133                 error "failed to create $NR files in $DIR/$tdir"
13134
13135         cancel_lru_locks mdc
13136         ls -l $DIR/$tdir > /dev/null
13137
13138         local NSDIR=""
13139         local LRU_SIZE=0
13140         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13141                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13142                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13143                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13144                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13145                         log "NSDIR=$NSDIR"
13146                         log "NS=$(basename $NSDIR)"
13147                         break
13148                 fi
13149         done
13150
13151         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13152                 skip "Not enough cached locks created!"
13153         fi
13154         log "LRU=$LRU_SIZE"
13155
13156         local SLEEP=30
13157
13158         # We know that lru resize allows one client to hold $LIMIT locks
13159         # for 10h. After that locks begin to be killed by client.
13160         local MAX_HRS=10
13161         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13162         log "LIMIT=$LIMIT"
13163         if [ $LIMIT -lt $LRU_SIZE ]; then
13164                 skip "Limit is too small $LIMIT"
13165         fi
13166
13167         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13168         # killing locks. Some time was spent for creating locks. This means
13169         # that up to the moment of sleep finish we must have killed some of
13170         # them (10-100 locks). This depends on how fast ther were created.
13171         # Many of them were touched in almost the same moment and thus will
13172         # be killed in groups.
13173         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13174
13175         # Use $LRU_SIZE_B here to take into account real number of locks
13176         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13177         local LRU_SIZE_B=$LRU_SIZE
13178         log "LVF=$LVF"
13179         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13180         log "OLD_LVF=$OLD_LVF"
13181         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13182
13183         # Let's make sure that we really have some margin. Client checks
13184         # cached locks every 10 sec.
13185         SLEEP=$((SLEEP+20))
13186         log "Sleep ${SLEEP} sec"
13187         local SEC=0
13188         while ((SEC<$SLEEP)); do
13189                 echo -n "..."
13190                 sleep 5
13191                 SEC=$((SEC+5))
13192                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13193                 echo -n "$LRU_SIZE"
13194         done
13195         echo ""
13196         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13197         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13198
13199         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13200                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13201                 unlinkmany $DIR/$tdir/f $NR
13202                 return
13203         }
13204
13205         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13206         log "unlink $NR files at $DIR/$tdir"
13207         unlinkmany $DIR/$tdir/f $NR
13208 }
13209 run_test 124a "lru resize ======================================="
13210
13211 get_max_pool_limit()
13212 {
13213         local limit=$($LCTL get_param \
13214                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13215         local max=0
13216         for l in $limit; do
13217                 if [[ $l -gt $max ]]; then
13218                         max=$l
13219                 fi
13220         done
13221         echo $max
13222 }
13223
13224 test_124b() {
13225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13226         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13227                 skip_env "no lru resize on server"
13228
13229         LIMIT=$(get_max_pool_limit)
13230
13231         NR=$(($(default_lru_size)*20))
13232         if [[ $NR -gt $LIMIT ]]; then
13233                 log "Limit lock number by $LIMIT locks"
13234                 NR=$LIMIT
13235         fi
13236
13237         IFree=$(mdsrate_inodes_available)
13238         if [ $IFree -lt $NR ]; then
13239                 log "Limit lock number by $IFree inodes"
13240                 NR=$IFree
13241         fi
13242
13243         lru_resize_disable mdc
13244         test_mkdir -p $DIR/$tdir/disable_lru_resize
13245
13246         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13247         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13248         cancel_lru_locks mdc
13249         stime=`date +%s`
13250         PID=""
13251         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13252         PID="$PID $!"
13253         sleep 2
13254         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13255         PID="$PID $!"
13256         sleep 2
13257         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13258         PID="$PID $!"
13259         wait $PID
13260         etime=`date +%s`
13261         nolruresize_delta=$((etime-stime))
13262         log "ls -la time: $nolruresize_delta seconds"
13263         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13264         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13265
13266         lru_resize_enable mdc
13267         test_mkdir -p $DIR/$tdir/enable_lru_resize
13268
13269         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13270         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13271         cancel_lru_locks mdc
13272         stime=`date +%s`
13273         PID=""
13274         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13275         PID="$PID $!"
13276         sleep 2
13277         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13278         PID="$PID $!"
13279         sleep 2
13280         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13281         PID="$PID $!"
13282         wait $PID
13283         etime=`date +%s`
13284         lruresize_delta=$((etime-stime))
13285         log "ls -la time: $lruresize_delta seconds"
13286         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13287
13288         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13289                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13290         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13291                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13292         else
13293                 log "lru resize performs the same with no lru resize"
13294         fi
13295         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13296 }
13297 run_test 124b "lru resize (performance test) ======================="
13298
13299 test_124c() {
13300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13301         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13302                 skip_env "no lru resize on server"
13303
13304         # cache ununsed locks on client
13305         local nr=100
13306         cancel_lru_locks mdc
13307         test_mkdir $DIR/$tdir
13308         createmany -o $DIR/$tdir/f $nr ||
13309                 error "failed to create $nr files in $DIR/$tdir"
13310         ls -l $DIR/$tdir > /dev/null
13311
13312         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13313         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13314         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13315         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13316         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13317
13318         # set lru_max_age to 1 sec
13319         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13320         echo "sleep $((recalc_p * 2)) seconds..."
13321         sleep $((recalc_p * 2))
13322
13323         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13324         # restore lru_max_age
13325         $LCTL set_param -n $nsdir.lru_max_age $max_age
13326         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13327         unlinkmany $DIR/$tdir/f $nr
13328 }
13329 run_test 124c "LRUR cancel very aged locks"
13330
13331 test_124d() {
13332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13333         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13334                 skip_env "no lru resize on server"
13335
13336         # cache ununsed locks on client
13337         local nr=100
13338
13339         lru_resize_disable mdc
13340         stack_trap "lru_resize_enable mdc" EXIT
13341
13342         cancel_lru_locks mdc
13343
13344         # asynchronous object destroy at MDT could cause bl ast to client
13345         test_mkdir $DIR/$tdir
13346         createmany -o $DIR/$tdir/f $nr ||
13347                 error "failed to create $nr files in $DIR/$tdir"
13348         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13349
13350         ls -l $DIR/$tdir > /dev/null
13351
13352         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13353         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13354         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13355         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13356
13357         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13358
13359         # set lru_max_age to 1 sec
13360         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13361         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13362
13363         echo "sleep $((recalc_p * 2)) seconds..."
13364         sleep $((recalc_p * 2))
13365
13366         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13367
13368         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13369 }
13370 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13371
13372 test_125() { # 13358
13373         $LCTL get_param -n llite.*.client_type | grep -q local ||
13374                 skip "must run as local client"
13375         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13376                 skip_env "must have acl enabled"
13377         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13378
13379         test_mkdir $DIR/$tdir
13380         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13381         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13382         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13383 }
13384 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13385
13386 test_126() { # bug 12829/13455
13387         $GSS && skip_env "must run as gss disabled"
13388         $LCTL get_param -n llite.*.client_type | grep -q local ||
13389                 skip "must run as local client"
13390         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13391
13392         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13393         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13394         rm -f $DIR/$tfile
13395         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13396 }
13397 run_test 126 "check that the fsgid provided by the client is taken into account"
13398
13399 test_127a() { # bug 15521
13400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13401         local name count samp unit min max sum sumsq
13402
13403         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13404         echo "stats before reset"
13405         $LCTL get_param osc.*.stats
13406         $LCTL set_param osc.*.stats=0
13407         local fsize=$((2048 * 1024))
13408
13409         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13410         cancel_lru_locks osc
13411         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13412
13413         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13414         stack_trap "rm -f $TMP/$tfile.tmp"
13415         while read name count samp unit min max sum sumsq; do
13416                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13417                 [ ! $min ] && error "Missing min value for $name proc entry"
13418                 eval $name=$count || error "Wrong proc format"
13419
13420                 case $name in
13421                 read_bytes|write_bytes)
13422                         [[ "$unit" =~ "bytes" ]] ||
13423                                 error "unit is not 'bytes': $unit"
13424                         (( $min >= 4096 )) || error "min is too small: $min"
13425                         (( $min <= $fsize )) || error "min is too big: $min"
13426                         (( $max >= 4096 )) || error "max is too small: $max"
13427                         (( $max <= $fsize )) || error "max is too big: $max"
13428                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13429                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13430                                 error "sumsquare is too small: $sumsq"
13431                         (( $sumsq <= $fsize * $fsize )) ||
13432                                 error "sumsquare is too big: $sumsq"
13433                         ;;
13434                 ost_read|ost_write)
13435                         [[ "$unit" =~ "usec" ]] ||
13436                                 error "unit is not 'usec': $unit"
13437                         ;;
13438                 *)      ;;
13439                 esac
13440         done < $DIR/$tfile.tmp
13441
13442         #check that we actually got some stats
13443         [ "$read_bytes" ] || error "Missing read_bytes stats"
13444         [ "$write_bytes" ] || error "Missing write_bytes stats"
13445         [ "$read_bytes" != 0 ] || error "no read done"
13446         [ "$write_bytes" != 0 ] || error "no write done"
13447 }
13448 run_test 127a "verify the client stats are sane"
13449
13450 test_127b() { # bug LU-333
13451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13452         local name count samp unit min max sum sumsq
13453
13454         echo "stats before reset"
13455         $LCTL get_param llite.*.stats
13456         $LCTL set_param llite.*.stats=0
13457
13458         # perform 2 reads and writes so MAX is different from SUM.
13459         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13460         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13461         cancel_lru_locks osc
13462         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13463         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13464
13465         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13466         stack_trap "rm -f $TMP/$tfile.tmp"
13467         while read name count samp unit min max sum sumsq; do
13468                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13469                 eval $name=$count || error "Wrong proc format"
13470
13471                 case $name in
13472                 read_bytes|write_bytes)
13473                         [[ "$unit" =~ "bytes" ]] ||
13474                                 error "unit is not 'bytes': $unit"
13475                         (( $count == 2 )) || error "count is not 2: $count"
13476                         (( $min == $PAGE_SIZE )) ||
13477                                 error "min is not $PAGE_SIZE: $min"
13478                         (( $max == $PAGE_SIZE )) ||
13479                                 error "max is not $PAGE_SIZE: $max"
13480                         (( $sum == $PAGE_SIZE * 2 )) ||
13481                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13482                         ;;
13483                 read|write)
13484                         [[ "$unit" =~ "usec" ]] ||
13485                                 error "unit is not 'usec': $unit"
13486                         ;;
13487                 *)      ;;
13488                 esac
13489         done < $TMP/$tfile.tmp
13490
13491         #check that we actually got some stats
13492         [ "$read_bytes" ] || error "Missing read_bytes stats"
13493         [ "$write_bytes" ] || error "Missing write_bytes stats"
13494         [ "$read_bytes" != 0 ] || error "no read done"
13495         [ "$write_bytes" != 0 ] || error "no write done"
13496 }
13497 run_test 127b "verify the llite client stats are sane"
13498
13499 test_127c() { # LU-12394
13500         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13501         local size
13502         local bsize
13503         local reads
13504         local writes
13505         local count
13506
13507         $LCTL set_param llite.*.extents_stats=1
13508         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13509
13510         # Use two stripes so there is enough space in default config
13511         $LFS setstripe -c 2 $DIR/$tfile
13512
13513         # Extent stats start at 0-4K and go in power of two buckets
13514         # LL_HIST_START = 12 --> 2^12 = 4K
13515         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13516         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13517         # small configs
13518         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13519                 do
13520                 # Write and read, 2x each, second time at a non-zero offset
13521                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13522                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13523                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13524                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13525                 rm -f $DIR/$tfile
13526         done
13527
13528         $LCTL get_param llite.*.extents_stats
13529
13530         count=2
13531         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13532                 do
13533                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13534                                 grep -m 1 $bsize)
13535                 reads=$(echo $bucket | awk '{print $5}')
13536                 writes=$(echo $bucket | awk '{print $9}')
13537                 [ "$reads" -eq $count ] ||
13538                         error "$reads reads in < $bsize bucket, expect $count"
13539                 [ "$writes" -eq $count ] ||
13540                         error "$writes writes in < $bsize bucket, expect $count"
13541         done
13542
13543         # Test mmap write and read
13544         $LCTL set_param llite.*.extents_stats=c
13545         size=512
13546         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13547         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13548         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13549
13550         $LCTL get_param llite.*.extents_stats
13551
13552         count=$(((size*1024) / PAGE_SIZE))
13553
13554         bsize=$((2 * PAGE_SIZE / 1024))K
13555
13556         bucket=$($LCTL get_param -n llite.*.extents_stats |
13557                         grep -m 1 $bsize)
13558         reads=$(echo $bucket | awk '{print $5}')
13559         writes=$(echo $bucket | awk '{print $9}')
13560         # mmap writes fault in the page first, creating an additonal read
13561         [ "$reads" -eq $((2 * count)) ] ||
13562                 error "$reads reads in < $bsize bucket, expect $count"
13563         [ "$writes" -eq $count ] ||
13564                 error "$writes writes in < $bsize bucket, expect $count"
13565 }
13566 run_test 127c "test llite extent stats with regular & mmap i/o"
13567
13568 test_128() { # bug 15212
13569         touch $DIR/$tfile
13570         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13571                 find $DIR/$tfile
13572                 find $DIR/$tfile
13573         EOF
13574
13575         result=$(grep error $TMP/$tfile.log)
13576         rm -f $DIR/$tfile $TMP/$tfile.log
13577         [ -z "$result" ] ||
13578                 error "consecutive find's under interactive lfs failed"
13579 }
13580 run_test 128 "interactive lfs for 2 consecutive find's"
13581
13582 set_dir_limits () {
13583         local mntdev
13584         local canondev
13585         local node
13586
13587         local ldproc=/proc/fs/ldiskfs
13588         local facets=$(get_facets MDS)
13589
13590         for facet in ${facets//,/ }; do
13591                 canondev=$(ldiskfs_canon \
13592                            *.$(convert_facet2label $facet).mntdev $facet)
13593                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13594                         ldproc=/sys/fs/ldiskfs
13595                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13596                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13597         done
13598 }
13599
13600 check_mds_dmesg() {
13601         local facets=$(get_facets MDS)
13602         for facet in ${facets//,/ }; do
13603                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13604         done
13605         return 1
13606 }
13607
13608 test_129() {
13609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13610         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13611                 skip "Need MDS version with at least 2.5.56"
13612         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13613                 skip_env "ldiskfs only test"
13614         fi
13615         remote_mds_nodsh && skip "remote MDS with nodsh"
13616
13617         local ENOSPC=28
13618         local has_warning=false
13619
13620         rm -rf $DIR/$tdir
13621         mkdir -p $DIR/$tdir
13622
13623         # block size of mds1
13624         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13625         set_dir_limits $maxsize $((maxsize * 6 / 8))
13626         stack_trap "set_dir_limits 0 0"
13627         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13628         local dirsize=$(stat -c%s "$DIR/$tdir")
13629         local nfiles=0
13630         while (( $dirsize <= $maxsize )); do
13631                 $MCREATE $DIR/$tdir/file_base_$nfiles
13632                 rc=$?
13633                 # check two errors:
13634                 # ENOSPC for ext4 max_dir_size, which has been used since
13635                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13636                 if (( rc == ENOSPC )); then
13637                         set_dir_limits 0 0
13638                         echo "rc=$rc returned as expected after $nfiles files"
13639
13640                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13641                                 error "create failed w/o dir size limit"
13642
13643                         # messages may be rate limited if test is run repeatedly
13644                         check_mds_dmesg '"is approaching max"' ||
13645                                 echo "warning message should be output"
13646                         check_mds_dmesg '"has reached max"' ||
13647                                 echo "reached message should be output"
13648
13649                         dirsize=$(stat -c%s "$DIR/$tdir")
13650
13651                         [[ $dirsize -ge $maxsize ]] && return 0
13652                         error "dirsize $dirsize < $maxsize after $nfiles files"
13653                 elif (( rc != 0 )); then
13654                         break
13655                 fi
13656                 nfiles=$((nfiles + 1))
13657                 dirsize=$(stat -c%s "$DIR/$tdir")
13658         done
13659
13660         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13661 }
13662 run_test 129 "test directory size limit ========================"
13663
13664 OLDIFS="$IFS"
13665 cleanup_130() {
13666         trap 0
13667         IFS="$OLDIFS"
13668 }
13669
13670 test_130a() {
13671         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13672         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13673
13674         trap cleanup_130 EXIT RETURN
13675
13676         local fm_file=$DIR/$tfile
13677         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13678         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13679                 error "dd failed for $fm_file"
13680
13681         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13682         filefrag -ves $fm_file
13683         RC=$?
13684         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13685                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13686         [ $RC != 0 ] && error "filefrag $fm_file failed"
13687
13688         filefrag_op=$(filefrag -ve -k $fm_file |
13689                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13690         lun=$($LFS getstripe -i $fm_file)
13691
13692         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13693         IFS=$'\n'
13694         tot_len=0
13695         for line in $filefrag_op
13696         do
13697                 frag_lun=`echo $line | cut -d: -f5`
13698                 ext_len=`echo $line | cut -d: -f4`
13699                 if (( $frag_lun != $lun )); then
13700                         cleanup_130
13701                         error "FIEMAP on 1-stripe file($fm_file) failed"
13702                         return
13703                 fi
13704                 (( tot_len += ext_len ))
13705         done
13706
13707         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13708                 cleanup_130
13709                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13710                 return
13711         fi
13712
13713         cleanup_130
13714
13715         echo "FIEMAP on single striped file succeeded"
13716 }
13717 run_test 130a "FIEMAP (1-stripe file)"
13718
13719 test_130b() {
13720         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13721
13722         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13723         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13724
13725         trap cleanup_130 EXIT RETURN
13726
13727         local fm_file=$DIR/$tfile
13728         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13729                         error "setstripe on $fm_file"
13730         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13731                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13732
13733         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13734                 error "dd failed on $fm_file"
13735
13736         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13737         filefrag_op=$(filefrag -ve -k $fm_file |
13738                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13739
13740         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13741                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13742
13743         IFS=$'\n'
13744         tot_len=0
13745         num_luns=1
13746         for line in $filefrag_op
13747         do
13748                 frag_lun=$(echo $line | cut -d: -f5 |
13749                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13750                 ext_len=$(echo $line | cut -d: -f4)
13751                 if (( $frag_lun != $last_lun )); then
13752                         if (( tot_len != 1024 )); then
13753                                 cleanup_130
13754                                 error "FIEMAP on $fm_file failed; returned " \
13755                                 "len $tot_len for OST $last_lun instead of 1024"
13756                                 return
13757                         else
13758                                 (( num_luns += 1 ))
13759                                 tot_len=0
13760                         fi
13761                 fi
13762                 (( tot_len += ext_len ))
13763                 last_lun=$frag_lun
13764         done
13765         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13766                 cleanup_130
13767                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13768                         "luns or wrong len for OST $last_lun"
13769                 return
13770         fi
13771
13772         cleanup_130
13773
13774         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13775 }
13776 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13777
13778 test_130c() {
13779         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13780
13781         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13782         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13783
13784         trap cleanup_130 EXIT RETURN
13785
13786         local fm_file=$DIR/$tfile
13787         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13788         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13789                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13790
13791         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13792                         error "dd failed on $fm_file"
13793
13794         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13795         filefrag_op=$(filefrag -ve -k $fm_file |
13796                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13797
13798         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13799                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13800
13801         IFS=$'\n'
13802         tot_len=0
13803         num_luns=1
13804         for line in $filefrag_op
13805         do
13806                 frag_lun=$(echo $line | cut -d: -f5 |
13807                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13808                 ext_len=$(echo $line | cut -d: -f4)
13809                 if (( $frag_lun != $last_lun )); then
13810                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13811                         if (( logical != 512 )); then
13812                                 cleanup_130
13813                                 error "FIEMAP on $fm_file failed; returned " \
13814                                 "logical start for lun $logical instead of 512"
13815                                 return
13816                         fi
13817                         if (( tot_len != 512 )); then
13818                                 cleanup_130
13819                                 error "FIEMAP on $fm_file failed; returned " \
13820                                 "len $tot_len for OST $last_lun instead of 1024"
13821                                 return
13822                         else
13823                                 (( num_luns += 1 ))
13824                                 tot_len=0
13825                         fi
13826                 fi
13827                 (( tot_len += ext_len ))
13828                 last_lun=$frag_lun
13829         done
13830         if (( num_luns != 2 || tot_len != 512 )); then
13831                 cleanup_130
13832                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13833                         "luns or wrong len for OST $last_lun"
13834                 return
13835         fi
13836
13837         cleanup_130
13838
13839         echo "FIEMAP on 2-stripe file with hole succeeded"
13840 }
13841 run_test 130c "FIEMAP (2-stripe file with hole)"
13842
13843 test_130d() {
13844         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13845
13846         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13847         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13848
13849         trap cleanup_130 EXIT RETURN
13850
13851         local fm_file=$DIR/$tfile
13852         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13853                         error "setstripe on $fm_file"
13854         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13855                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13856
13857         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13858         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13859                 error "dd failed on $fm_file"
13860
13861         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13862         filefrag_op=$(filefrag -ve -k $fm_file |
13863                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13864
13865         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13866                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13867
13868         IFS=$'\n'
13869         tot_len=0
13870         num_luns=1
13871         for line in $filefrag_op
13872         do
13873                 frag_lun=$(echo $line | cut -d: -f5 |
13874                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13875                 ext_len=$(echo $line | cut -d: -f4)
13876                 if (( $frag_lun != $last_lun )); then
13877                         if (( tot_len != 1024 )); then
13878                                 cleanup_130
13879                                 error "FIEMAP on $fm_file failed; returned " \
13880                                 "len $tot_len for OST $last_lun instead of 1024"
13881                                 return
13882                         else
13883                                 (( num_luns += 1 ))
13884                                 tot_len=0
13885                         fi
13886                 fi
13887                 (( tot_len += ext_len ))
13888                 last_lun=$frag_lun
13889         done
13890         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13891                 cleanup_130
13892                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13893                         "luns or wrong len for OST $last_lun"
13894                 return
13895         fi
13896
13897         cleanup_130
13898
13899         echo "FIEMAP on N-stripe file succeeded"
13900 }
13901 run_test 130d "FIEMAP (N-stripe file)"
13902
13903 test_130e() {
13904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13905
13906         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13907         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13908
13909         trap cleanup_130 EXIT RETURN
13910
13911         local fm_file=$DIR/$tfile
13912         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13913
13914         NUM_BLKS=512
13915         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13916         for ((i = 0; i < $NUM_BLKS; i++)); do
13917                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13918                         conv=notrunc > /dev/null 2>&1
13919         done
13920
13921         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13922         filefrag_op=$(filefrag -ve -k $fm_file |
13923                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13924
13925         last_lun=$(echo $filefrag_op | cut -d: -f5)
13926
13927         IFS=$'\n'
13928         tot_len=0
13929         num_luns=1
13930         for line in $filefrag_op; do
13931                 frag_lun=$(echo $line | cut -d: -f5)
13932                 ext_len=$(echo $line | cut -d: -f4)
13933                 if [[ "$frag_lun" != "$last_lun" ]]; then
13934                         if (( tot_len != $EXPECTED_LEN )); then
13935                                 cleanup_130
13936                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13937                         else
13938                                 (( num_luns += 1 ))
13939                                 tot_len=0
13940                         fi
13941                 fi
13942                 (( tot_len += ext_len ))
13943                 last_lun=$frag_lun
13944         done
13945         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13946                 cleanup_130
13947                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13948         fi
13949
13950         echo "FIEMAP with continuation calls succeeded"
13951 }
13952 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13953
13954 test_130f() {
13955         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13956         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13957
13958         local fm_file=$DIR/$tfile
13959         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13960                 error "multiop create with lov_delay_create on $fm_file"
13961
13962         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13963         filefrag_extents=$(filefrag -vek $fm_file |
13964                            awk '/extents? found/ { print $2 }')
13965         if [[ "$filefrag_extents" != "0" ]]; then
13966                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13967         fi
13968
13969         rm -f $fm_file
13970 }
13971 run_test 130f "FIEMAP (unstriped file)"
13972
13973 test_130g() {
13974         local file=$DIR/$tfile
13975         local nr=$((OSTCOUNT * 100))
13976
13977         $LFS setstripe -C $nr $file ||
13978                 error "failed to setstripe -C $nr $file"
13979
13980         dd if=/dev/zero of=$file count=$nr bs=1M
13981         sync
13982         nr=$($LFS getstripe -c $file)
13983
13984         local extents=$(filefrag -v $file |
13985                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13986
13987         echo "filefrag list $extents extents in file with stripecount $nr"
13988         if (( extents < nr )); then
13989                 $LFS getstripe $file
13990                 filefrag -v $file
13991                 error "filefrag printed $extents < $nr extents"
13992         fi
13993
13994         rm -f $file
13995 }
13996 run_test 130g "FIEMAP (overstripe file)"
13997
13998 # Test for writev/readv
13999 test_131a() {
14000         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14001                 error "writev test failed"
14002         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14003                 error "readv failed"
14004         rm -f $DIR/$tfile
14005 }
14006 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14007
14008 test_131b() {
14009         local fsize=$((524288 + 1048576 + 1572864))
14010         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14011                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14012                         error "append writev test failed"
14013
14014         ((fsize += 1572864 + 1048576))
14015         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14016                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14017                         error "append writev test failed"
14018         rm -f $DIR/$tfile
14019 }
14020 run_test 131b "test append writev"
14021
14022 test_131c() {
14023         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14024         error "NOT PASS"
14025 }
14026 run_test 131c "test read/write on file w/o objects"
14027
14028 test_131d() {
14029         rwv -f $DIR/$tfile -w -n 1 1572864
14030         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14031         if [ "$NOB" != 1572864 ]; then
14032                 error "Short read filed: read $NOB bytes instead of 1572864"
14033         fi
14034         rm -f $DIR/$tfile
14035 }
14036 run_test 131d "test short read"
14037
14038 test_131e() {
14039         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14040         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14041         error "read hitting hole failed"
14042         rm -f $DIR/$tfile
14043 }
14044 run_test 131e "test read hitting hole"
14045
14046 check_stats() {
14047         local facet=$1
14048         local op=$2
14049         local want=${3:-0}
14050         local res
14051
14052         case $facet in
14053         mds*) res=$(do_facet $facet \
14054                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
14055                  ;;
14056         ost*) res=$(do_facet $facet \
14057                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
14058                  ;;
14059         *) error "Wrong facet '$facet'" ;;
14060         esac
14061         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14062         # if the argument $3 is zero, it means any stat increment is ok.
14063         if [[ $want -gt 0 ]]; then
14064                 local count=$(echo $res | awk '{ print $2 }')
14065                 [[ $count -ne $want ]] &&
14066                         error "The $op counter on $facet is $count, not $want"
14067         fi
14068 }
14069
14070 test_133a() {
14071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14072         remote_ost_nodsh && skip "remote OST with nodsh"
14073         remote_mds_nodsh && skip "remote MDS with nodsh"
14074         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14075                 skip_env "MDS doesn't support rename stats"
14076
14077         local testdir=$DIR/${tdir}/stats_testdir
14078
14079         mkdir -p $DIR/${tdir}
14080
14081         # clear stats.
14082         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14083         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14084
14085         # verify mdt stats first.
14086         mkdir ${testdir} || error "mkdir failed"
14087         check_stats $SINGLEMDS "mkdir" 1
14088         touch ${testdir}/${tfile} || error "touch failed"
14089         check_stats $SINGLEMDS "open" 1
14090         check_stats $SINGLEMDS "close" 1
14091         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14092                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14093                 check_stats $SINGLEMDS "mknod" 2
14094         }
14095         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14096         check_stats $SINGLEMDS "unlink" 1
14097         rm -f ${testdir}/${tfile} || error "file remove failed"
14098         check_stats $SINGLEMDS "unlink" 2
14099
14100         # remove working dir and check mdt stats again.
14101         rmdir ${testdir} || error "rmdir failed"
14102         check_stats $SINGLEMDS "rmdir" 1
14103
14104         local testdir1=$DIR/${tdir}/stats_testdir1
14105         mkdir -p ${testdir}
14106         mkdir -p ${testdir1}
14107         touch ${testdir1}/test1
14108         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14109         check_stats $SINGLEMDS "crossdir_rename" 1
14110
14111         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14112         check_stats $SINGLEMDS "samedir_rename" 1
14113
14114         rm -rf $DIR/${tdir}
14115 }
14116 run_test 133a "Verifying MDT stats ========================================"
14117
14118 test_133b() {
14119         local res
14120
14121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14122         remote_ost_nodsh && skip "remote OST with nodsh"
14123         remote_mds_nodsh && skip "remote MDS with nodsh"
14124
14125         local testdir=$DIR/${tdir}/stats_testdir
14126
14127         mkdir -p ${testdir} || error "mkdir failed"
14128         touch ${testdir}/${tfile} || error "touch failed"
14129         cancel_lru_locks mdc
14130
14131         # clear stats.
14132         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14133         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14134
14135         # extra mdt stats verification.
14136         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14137         check_stats $SINGLEMDS "setattr" 1
14138         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14139         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14140         then            # LU-1740
14141                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14142                 check_stats $SINGLEMDS "getattr" 1
14143         fi
14144         rm -rf $DIR/${tdir}
14145
14146         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14147         # so the check below is not reliable
14148         [ $MDSCOUNT -eq 1 ] || return 0
14149
14150         # Sleep to avoid a cached response.
14151         #define OBD_STATFS_CACHE_SECONDS 1
14152         sleep 2
14153         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14154         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14155         $LFS df || error "lfs failed"
14156         check_stats $SINGLEMDS "statfs" 1
14157
14158         # check aggregated statfs (LU-10018)
14159         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14160                 return 0
14161         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14162                 return 0
14163         sleep 2
14164         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14165         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14166         df $DIR
14167         check_stats $SINGLEMDS "statfs" 1
14168
14169         # We want to check that the client didn't send OST_STATFS to
14170         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14171         # extra care is needed here.
14172         if remote_mds; then
14173                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14174                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14175
14176                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14177                 [ "$res" ] && error "OST got STATFS"
14178         fi
14179
14180         return 0
14181 }
14182 run_test 133b "Verifying extra MDT stats =================================="
14183
14184 test_133c() {
14185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14186         remote_ost_nodsh && skip "remote OST with nodsh"
14187         remote_mds_nodsh && skip "remote MDS with nodsh"
14188
14189         local testdir=$DIR/$tdir/stats_testdir
14190
14191         test_mkdir -p $testdir
14192
14193         # verify obdfilter stats.
14194         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14195         sync
14196         cancel_lru_locks osc
14197         wait_delete_completed
14198
14199         # clear stats.
14200         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14201         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14202
14203         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14204                 error "dd failed"
14205         sync
14206         cancel_lru_locks osc
14207         check_stats ost1 "write" 1
14208
14209         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14210         check_stats ost1 "read" 1
14211
14212         > $testdir/$tfile || error "truncate failed"
14213         check_stats ost1 "punch" 1
14214
14215         rm -f $testdir/$tfile || error "file remove failed"
14216         wait_delete_completed
14217         check_stats ost1 "destroy" 1
14218
14219         rm -rf $DIR/$tdir
14220 }
14221 run_test 133c "Verifying OST stats ========================================"
14222
14223 order_2() {
14224         local value=$1
14225         local orig=$value
14226         local order=1
14227
14228         while [ $value -ge 2 ]; do
14229                 order=$((order*2))
14230                 value=$((value/2))
14231         done
14232
14233         if [ $orig -gt $order ]; then
14234                 order=$((order*2))
14235         fi
14236         echo $order
14237 }
14238
14239 size_in_KMGT() {
14240     local value=$1
14241     local size=('K' 'M' 'G' 'T');
14242     local i=0
14243     local size_string=$value
14244
14245     while [ $value -ge 1024 ]; do
14246         if [ $i -gt 3 ]; then
14247             #T is the biggest unit we get here, if that is bigger,
14248             #just return XXXT
14249             size_string=${value}T
14250             break
14251         fi
14252         value=$((value >> 10))
14253         if [ $value -lt 1024 ]; then
14254             size_string=${value}${size[$i]}
14255             break
14256         fi
14257         i=$((i + 1))
14258     done
14259
14260     echo $size_string
14261 }
14262
14263 get_rename_size() {
14264         local size=$1
14265         local context=${2:-.}
14266         local sample=$(do_facet $SINGLEMDS $LCTL \
14267                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14268                 grep -A1 $context |
14269                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14270         echo $sample
14271 }
14272
14273 test_133d() {
14274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14275         remote_ost_nodsh && skip "remote OST with nodsh"
14276         remote_mds_nodsh && skip "remote MDS with nodsh"
14277         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14278                 skip_env "MDS doesn't support rename stats"
14279
14280         local testdir1=$DIR/${tdir}/stats_testdir1
14281         local testdir2=$DIR/${tdir}/stats_testdir2
14282         mkdir -p $DIR/${tdir}
14283
14284         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14285
14286         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14287         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14288
14289         createmany -o $testdir1/test 512 || error "createmany failed"
14290
14291         # check samedir rename size
14292         mv ${testdir1}/test0 ${testdir1}/test_0
14293
14294         local testdir1_size=$(ls -l $DIR/${tdir} |
14295                 awk '/stats_testdir1/ {print $5}')
14296         local testdir2_size=$(ls -l $DIR/${tdir} |
14297                 awk '/stats_testdir2/ {print $5}')
14298
14299         testdir1_size=$(order_2 $testdir1_size)
14300         testdir2_size=$(order_2 $testdir2_size)
14301
14302         testdir1_size=$(size_in_KMGT $testdir1_size)
14303         testdir2_size=$(size_in_KMGT $testdir2_size)
14304
14305         echo "source rename dir size: ${testdir1_size}"
14306         echo "target rename dir size: ${testdir2_size}"
14307
14308         local cmd="do_facet $SINGLEMDS $LCTL "
14309         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14310
14311         eval $cmd || error "$cmd failed"
14312         local samedir=$($cmd | grep 'same_dir')
14313         local same_sample=$(get_rename_size $testdir1_size)
14314         [ -z "$samedir" ] && error "samedir_rename_size count error"
14315         [[ $same_sample -eq 1 ]] ||
14316                 error "samedir_rename_size error $same_sample"
14317         echo "Check same dir rename stats success"
14318
14319         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14320
14321         # check crossdir rename size
14322         mv ${testdir1}/test_0 ${testdir2}/test_0
14323
14324         testdir1_size=$(ls -l $DIR/${tdir} |
14325                 awk '/stats_testdir1/ {print $5}')
14326         testdir2_size=$(ls -l $DIR/${tdir} |
14327                 awk '/stats_testdir2/ {print $5}')
14328
14329         testdir1_size=$(order_2 $testdir1_size)
14330         testdir2_size=$(order_2 $testdir2_size)
14331
14332         testdir1_size=$(size_in_KMGT $testdir1_size)
14333         testdir2_size=$(size_in_KMGT $testdir2_size)
14334
14335         echo "source rename dir size: ${testdir1_size}"
14336         echo "target rename dir size: ${testdir2_size}"
14337
14338         eval $cmd || error "$cmd failed"
14339         local crossdir=$($cmd | grep 'crossdir')
14340         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14341         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14342         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14343         [[ $src_sample -eq 1 ]] ||
14344                 error "crossdir_rename_size error $src_sample"
14345         [[ $tgt_sample -eq 1 ]] ||
14346                 error "crossdir_rename_size error $tgt_sample"
14347         echo "Check cross dir rename stats success"
14348         rm -rf $DIR/${tdir}
14349 }
14350 run_test 133d "Verifying rename_stats ========================================"
14351
14352 test_133e() {
14353         remote_mds_nodsh && skip "remote MDS with nodsh"
14354         remote_ost_nodsh && skip "remote OST with nodsh"
14355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14356
14357         local testdir=$DIR/${tdir}/stats_testdir
14358         local ctr f0 f1 bs=32768 count=42 sum
14359
14360         mkdir -p ${testdir} || error "mkdir failed"
14361
14362         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14363
14364         for ctr in {write,read}_bytes; do
14365                 sync
14366                 cancel_lru_locks osc
14367
14368                 do_facet ost1 $LCTL set_param -n \
14369                         "obdfilter.*.exports.clear=clear"
14370
14371                 if [ $ctr = write_bytes ]; then
14372                         f0=/dev/zero
14373                         f1=${testdir}/${tfile}
14374                 else
14375                         f0=${testdir}/${tfile}
14376                         f1=/dev/null
14377                 fi
14378
14379                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14380                         error "dd failed"
14381                 sync
14382                 cancel_lru_locks osc
14383
14384                 sum=$(do_facet ost1 $LCTL get_param \
14385                         "obdfilter.*.exports.*.stats" |
14386                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14387                                 $1 == ctr { sum += $7 }
14388                                 END { printf("%0.0f", sum) }')
14389
14390                 if ((sum != bs * count)); then
14391                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14392                 fi
14393         done
14394
14395         rm -rf $DIR/${tdir}
14396 }
14397 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14398
14399 test_133f() {
14400         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14401                 skip "too old lustre for get_param -R ($facet_ver)"
14402
14403         # verifying readability.
14404         $LCTL get_param -R '*' &> /dev/null
14405
14406         # Verifing writability with badarea_io.
14407         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14408         local skipped_params='force_lbug|changelog_mask|daemon_file'
14409         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14410                 egrep -v "$skipped_params" |
14411                 xargs -n 1 find $proc_dirs -name |
14412                 xargs -n 1 badarea_io ||
14413                 error "client badarea_io failed"
14414
14415         # remount the FS in case writes/reads /proc break the FS
14416         cleanup || error "failed to unmount"
14417         setup || error "failed to setup"
14418 }
14419 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14420
14421 test_133g() {
14422         remote_mds_nodsh && skip "remote MDS with nodsh"
14423         remote_ost_nodsh && skip "remote OST with nodsh"
14424
14425         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14426         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14427         local facet
14428         for facet in mds1 ost1; do
14429                 local facet_ver=$(lustre_version_code $facet)
14430                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14431                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14432                 else
14433                         log "$facet: too old lustre for get_param -R"
14434                 fi
14435                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14436                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14437                                 tr -d = | egrep -v $skipped_params |
14438                                 xargs -n 1 find $proc_dirs -name |
14439                                 xargs -n 1 badarea_io" ||
14440                                         error "$facet badarea_io failed"
14441                 else
14442                         skip_noexit "$facet: too old lustre for get_param -R"
14443                 fi
14444         done
14445
14446         # remount the FS in case writes/reads /proc break the FS
14447         cleanup || error "failed to unmount"
14448         setup || error "failed to setup"
14449 }
14450 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14451
14452 test_133h() {
14453         remote_mds_nodsh && skip "remote MDS with nodsh"
14454         remote_ost_nodsh && skip "remote OST with nodsh"
14455         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14456                 skip "Need MDS version at least 2.9.54"
14457
14458         local facet
14459         for facet in client mds1 ost1; do
14460                 # Get the list of files that are missing the terminating newline
14461                 local plist=$(do_facet $facet
14462                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14463                 local ent
14464                 for ent in $plist; do
14465                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14466                                 awk -v FS='\v' -v RS='\v\v' \
14467                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14468                                         print FILENAME}'" 2>/dev/null)
14469                         [ -z $missing ] || {
14470                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14471                                 error "file does not end with newline: $facet-$ent"
14472                         }
14473                 done
14474         done
14475 }
14476 run_test 133h "Proc files should end with newlines"
14477
14478 test_134a() {
14479         remote_mds_nodsh && skip "remote MDS with nodsh"
14480         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14481                 skip "Need MDS version at least 2.7.54"
14482
14483         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14484         cancel_lru_locks mdc
14485
14486         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14487         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14488         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14489
14490         local nr=1000
14491         createmany -o $DIR/$tdir/f $nr ||
14492                 error "failed to create $nr files in $DIR/$tdir"
14493         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14494
14495         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14496         do_facet mds1 $LCTL set_param fail_loc=0x327
14497         do_facet mds1 $LCTL set_param fail_val=500
14498         touch $DIR/$tdir/m
14499
14500         echo "sleep 10 seconds ..."
14501         sleep 10
14502         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14503
14504         do_facet mds1 $LCTL set_param fail_loc=0
14505         do_facet mds1 $LCTL set_param fail_val=0
14506         [ $lck_cnt -lt $unused ] ||
14507                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14508
14509         rm $DIR/$tdir/m
14510         unlinkmany $DIR/$tdir/f $nr
14511 }
14512 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14513
14514 test_134b() {
14515         remote_mds_nodsh && skip "remote MDS with nodsh"
14516         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14517                 skip "Need MDS version at least 2.7.54"
14518
14519         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14520         cancel_lru_locks mdc
14521
14522         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14523                         ldlm.lock_reclaim_threshold_mb)
14524         # disable reclaim temporarily
14525         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14526
14527         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14528         do_facet mds1 $LCTL set_param fail_loc=0x328
14529         do_facet mds1 $LCTL set_param fail_val=500
14530
14531         $LCTL set_param debug=+trace
14532
14533         local nr=600
14534         createmany -o $DIR/$tdir/f $nr &
14535         local create_pid=$!
14536
14537         echo "Sleep $TIMEOUT seconds ..."
14538         sleep $TIMEOUT
14539         if ! ps -p $create_pid  > /dev/null 2>&1; then
14540                 do_facet mds1 $LCTL set_param fail_loc=0
14541                 do_facet mds1 $LCTL set_param fail_val=0
14542                 do_facet mds1 $LCTL set_param \
14543                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14544                 error "createmany finished incorrectly!"
14545         fi
14546         do_facet mds1 $LCTL set_param fail_loc=0
14547         do_facet mds1 $LCTL set_param fail_val=0
14548         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14549         wait $create_pid || return 1
14550
14551         unlinkmany $DIR/$tdir/f $nr
14552 }
14553 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14554
14555 test_135() {
14556         remote_mds_nodsh && skip "remote MDS with nodsh"
14557         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14558                 skip "Need MDS version at least 2.13.50"
14559         local fname
14560
14561         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14562
14563 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14564         #set only one record at plain llog
14565         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14566
14567         #fill already existed plain llog each 64767
14568         #wrapping whole catalog
14569         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14570
14571         createmany -o $DIR/$tdir/$tfile_ 64700
14572         for (( i = 0; i < 64700; i = i + 2 ))
14573         do
14574                 rm $DIR/$tdir/$tfile_$i &
14575                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14576                 local pid=$!
14577                 wait $pid
14578         done
14579
14580         #waiting osp synchronization
14581         wait_delete_completed
14582 }
14583 run_test 135 "Race catalog processing"
14584
14585 test_136() {
14586         remote_mds_nodsh && skip "remote MDS with nodsh"
14587         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14588                 skip "Need MDS version at least 2.13.50"
14589         local fname
14590
14591         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14592         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14593         #set only one record at plain llog
14594 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14595         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14596
14597         #fill already existed 2 plain llogs each 64767
14598         #wrapping whole catalog
14599         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14600         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14601         wait_delete_completed
14602
14603         createmany -o $DIR/$tdir/$tfile_ 10
14604         sleep 25
14605
14606         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14607         for (( i = 0; i < 10; i = i + 3 ))
14608         do
14609                 rm $DIR/$tdir/$tfile_$i &
14610                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14611                 local pid=$!
14612                 wait $pid
14613                 sleep 7
14614                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14615         done
14616
14617         #waiting osp synchronization
14618         wait_delete_completed
14619 }
14620 run_test 136 "Race catalog processing 2"
14621
14622 test_140() { #bug-17379
14623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14624
14625         test_mkdir $DIR/$tdir
14626         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14627         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14628
14629         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14630         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14631         local i=0
14632         while i=$((i + 1)); do
14633                 test_mkdir $i
14634                 cd $i || error "Changing to $i"
14635                 ln -s ../stat stat || error "Creating stat symlink"
14636                 # Read the symlink until ELOOP present,
14637                 # not LBUGing the system is considered success,
14638                 # we didn't overrun the stack.
14639                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14640                 if [ $ret -ne 0 ]; then
14641                         if [ $ret -eq 40 ]; then
14642                                 break  # -ELOOP
14643                         else
14644                                 error "Open stat symlink"
14645                                         return
14646                         fi
14647                 fi
14648         done
14649         i=$((i - 1))
14650         echo "The symlink depth = $i"
14651         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14652                 error "Invalid symlink depth"
14653
14654         # Test recursive symlink
14655         ln -s symlink_self symlink_self
14656         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14657         echo "open symlink_self returns $ret"
14658         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14659 }
14660 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14661
14662 test_150a() {
14663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14664
14665         local TF="$TMP/$tfile"
14666
14667         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14668         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14669         cp $TF $DIR/$tfile
14670         cancel_lru_locks $OSC
14671         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14672         remount_client $MOUNT
14673         df -P $MOUNT
14674         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14675
14676         $TRUNCATE $TF 6000
14677         $TRUNCATE $DIR/$tfile 6000
14678         cancel_lru_locks $OSC
14679         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14680
14681         echo "12345" >>$TF
14682         echo "12345" >>$DIR/$tfile
14683         cancel_lru_locks $OSC
14684         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14685
14686         echo "12345" >>$TF
14687         echo "12345" >>$DIR/$tfile
14688         cancel_lru_locks $OSC
14689         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14690 }
14691 run_test 150a "truncate/append tests"
14692
14693 test_150b() {
14694         check_set_fallocate_or_skip
14695
14696         touch $DIR/$tfile
14697         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14698         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14699 }
14700 run_test 150b "Verify fallocate (prealloc) functionality"
14701
14702 test_150bb() {
14703         check_set_fallocate_or_skip
14704
14705         touch $DIR/$tfile
14706         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14707         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14708         > $DIR/$tfile
14709         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14710         # precomputed md5sum for 20MB of zeroes
14711         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14712         local sum=($(md5sum $DIR/$tfile))
14713
14714         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14715
14716         check_set_fallocate 1
14717
14718         > $DIR/$tfile
14719         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14720         sum=($(md5sum $DIR/$tfile))
14721
14722         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14723 }
14724 run_test 150bb "Verify fallocate modes both zero space"
14725
14726 test_150c() {
14727         check_set_fallocate_or_skip
14728         local striping="-c2"
14729
14730         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14731         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14732         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14733         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14734         local want=$((OSTCOUNT * 1048576))
14735
14736         # Must allocate all requested space, not more than 5% extra
14737         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14738                 error "bytes $bytes is not $want"
14739
14740         rm -f $DIR/$tfile
14741
14742         echo "verify fallocate on PFL file"
14743
14744         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14745
14746         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14747                 error "Create $DIR/$tfile failed"
14748         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14749         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14750         want=$((512 * 1048576))
14751
14752         # Must allocate all requested space, not more than 5% extra
14753         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14754                 error "bytes $bytes is not $want"
14755 }
14756 run_test 150c "Verify fallocate Size and Blocks"
14757
14758 test_150d() {
14759         check_set_fallocate_or_skip
14760         local striping="-c2"
14761
14762         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14763
14764         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14765         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14766                 error "setstripe failed"
14767         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14768         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14769         local want=$((OSTCOUNT * 1048576))
14770
14771         # Must allocate all requested space, not more than 5% extra
14772         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14773                 error "bytes $bytes is not $want"
14774 }
14775 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14776
14777 test_150e() {
14778         check_set_fallocate_or_skip
14779
14780         echo "df before:"
14781         $LFS df
14782         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14783         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14784                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14785
14786         # Find OST with Minimum Size
14787         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14788                        sort -un | head -1)
14789
14790         # Get 100MB per OST of the available space to reduce run time
14791         # else 60% of the available space if we are running SLOW tests
14792         if [ $SLOW == "no" ]; then
14793                 local space=$((1024 * 100 * OSTCOUNT))
14794         else
14795                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14796         fi
14797
14798         fallocate -l${space}k $DIR/$tfile ||
14799                 error "fallocate ${space}k $DIR/$tfile failed"
14800         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14801
14802         # get size immediately after fallocate. This should be correctly
14803         # updated
14804         local size=$(stat -c '%s' $DIR/$tfile)
14805         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14806
14807         # Sleep for a while for statfs to get updated. And not pull from cache.
14808         sleep 2
14809
14810         echo "df after fallocate:"
14811         $LFS df
14812
14813         (( size / 1024 == space )) || error "size $size != requested $space"
14814         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14815                 error "used $used < space $space"
14816
14817         rm $DIR/$tfile || error "rm failed"
14818         sync
14819         wait_delete_completed
14820
14821         echo "df after unlink:"
14822         $LFS df
14823 }
14824 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14825
14826 test_150f() {
14827         local size
14828         local blocks
14829         local want_size_before=20480 # in bytes
14830         local want_blocks_before=40 # 512 sized blocks
14831         local want_blocks_after=24  # 512 sized blocks
14832         local length=$(((want_blocks_before - want_blocks_after) * 512))
14833
14834         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14835                 skip "need at least 2.14.0 for fallocate punch"
14836
14837         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14838                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14839         fi
14840
14841         check_set_fallocate_or_skip
14842         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14843
14844         [[ "x$DOM" == "xyes" ]] &&
14845                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14846
14847         echo "Verify fallocate punch: Range within the file range"
14848         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14849                 error "dd failed for bs 4096 and count 5"
14850
14851         # Call fallocate with punch range which is within the file range
14852         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14853                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14854         # client must see changes immediately after fallocate
14855         size=$(stat -c '%s' $DIR/$tfile)
14856         blocks=$(stat -c '%b' $DIR/$tfile)
14857
14858         # Verify punch worked.
14859         (( blocks == want_blocks_after )) ||
14860                 error "punch failed: blocks $blocks != $want_blocks_after"
14861
14862         (( size == want_size_before )) ||
14863                 error "punch failed: size $size != $want_size_before"
14864
14865         # Verify there is hole in file
14866         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14867         # precomputed md5sum
14868         local expect="4a9a834a2db02452929c0a348273b4aa"
14869
14870         cksum=($(md5sum $DIR/$tfile))
14871         [[ "${cksum[0]}" == "$expect" ]] ||
14872                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14873
14874         # Start second sub-case for fallocate punch.
14875         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14876         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14877                 error "dd failed for bs 4096 and count 5"
14878
14879         # Punch range less than block size will have no change in block count
14880         want_blocks_after=40  # 512 sized blocks
14881
14882         # Punch overlaps two blocks and less than blocksize
14883         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14884                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14885         size=$(stat -c '%s' $DIR/$tfile)
14886         blocks=$(stat -c '%b' $DIR/$tfile)
14887
14888         # Verify punch worked.
14889         (( blocks == want_blocks_after )) ||
14890                 error "punch failed: blocks $blocks != $want_blocks_after"
14891
14892         (( size == want_size_before )) ||
14893                 error "punch failed: size $size != $want_size_before"
14894
14895         # Verify if range is really zero'ed out. We expect Zeros.
14896         # precomputed md5sum
14897         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14898         cksum=($(md5sum $DIR/$tfile))
14899         [[ "${cksum[0]}" == "$expect" ]] ||
14900                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14901 }
14902 run_test 150f "Verify fallocate punch functionality"
14903
14904 test_150g() {
14905         local space
14906         local size
14907         local blocks
14908         local blocks_after
14909         local size_after
14910         local BS=4096 # Block size in bytes
14911
14912         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14913                 skip "need at least 2.14.0 for fallocate punch"
14914
14915         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14916                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14917         fi
14918
14919         check_set_fallocate_or_skip
14920         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14921
14922         if [[ "x$DOM" == "xyes" ]]; then
14923                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14924                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14925         else
14926                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14927                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14928         fi
14929
14930         # Get 100MB per OST of the available space to reduce run time
14931         # else 60% of the available space if we are running SLOW tests
14932         if [ $SLOW == "no" ]; then
14933                 space=$((1024 * 100 * OSTCOUNT))
14934         else
14935                 # Find OST with Minimum Size
14936                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14937                         sort -un | head -1)
14938                 echo "min size OST: $space"
14939                 space=$(((space * 60)/100 * OSTCOUNT))
14940         fi
14941         # space in 1k units, round to 4k blocks
14942         local blkcount=$((space * 1024 / $BS))
14943
14944         echo "Verify fallocate punch: Very large Range"
14945         fallocate -l${space}k $DIR/$tfile ||
14946                 error "fallocate ${space}k $DIR/$tfile failed"
14947         # write 1M at the end, start and in the middle
14948         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14949                 error "dd failed: bs $BS count 256"
14950         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14951                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14952         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14953                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14954
14955         # Gather stats.
14956         size=$(stat -c '%s' $DIR/$tfile)
14957
14958         # gather punch length.
14959         local punch_size=$((size - (BS * 2)))
14960
14961         echo "punch_size = $punch_size"
14962         echo "size - punch_size: $((size - punch_size))"
14963         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14964
14965         # Call fallocate to punch all except 2 blocks. We leave the
14966         # first and the last block
14967         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14968         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14969                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14970
14971         size_after=$(stat -c '%s' $DIR/$tfile)
14972         blocks_after=$(stat -c '%b' $DIR/$tfile)
14973
14974         # Verify punch worked.
14975         # Size should be kept
14976         (( size == size_after )) ||
14977                 error "punch failed: size $size != $size_after"
14978
14979         # two 4k data blocks to remain plus possible 1 extra extent block
14980         (( blocks_after <= ((BS / 512) * 3) )) ||
14981                 error "too many blocks remains: $blocks_after"
14982
14983         # Verify that file has hole between the first and the last blocks
14984         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14985         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14986
14987         echo "Hole at [$hole_start, $hole_end)"
14988         (( hole_start == BS )) ||
14989                 error "no hole at offset $BS after punch"
14990
14991         (( hole_end == BS + punch_size )) ||
14992                 error "data at offset $hole_end < $((BS + punch_size))"
14993 }
14994 run_test 150g "Verify fallocate punch on large range"
14995
14996 #LU-2902 roc_hit was not able to read all values from lproc
14997 function roc_hit_init() {
14998         local list=$(comma_list $(osts_nodes))
14999         local dir=$DIR/$tdir-check
15000         local file=$dir/$tfile
15001         local BEFORE
15002         local AFTER
15003         local idx
15004
15005         test_mkdir $dir
15006         #use setstripe to do a write to every ost
15007         for i in $(seq 0 $((OSTCOUNT-1))); do
15008                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15009                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15010                 idx=$(printf %04x $i)
15011                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15012                         awk '$1 == "cache_access" {sum += $7}
15013                                 END { printf("%0.0f", sum) }')
15014
15015                 cancel_lru_locks osc
15016                 cat $file >/dev/null
15017
15018                 AFTER=$(get_osd_param $list *OST*$idx stats |
15019                         awk '$1 == "cache_access" {sum += $7}
15020                                 END { printf("%0.0f", sum) }')
15021
15022                 echo BEFORE:$BEFORE AFTER:$AFTER
15023                 if ! let "AFTER - BEFORE == 4"; then
15024                         rm -rf $dir
15025                         error "roc_hit is not safe to use"
15026                 fi
15027                 rm $file
15028         done
15029
15030         rm -rf $dir
15031 }
15032
15033 function roc_hit() {
15034         local list=$(comma_list $(osts_nodes))
15035         echo $(get_osd_param $list '' stats |
15036                 awk '$1 == "cache_hit" {sum += $7}
15037                         END { printf("%0.0f", sum) }')
15038 }
15039
15040 function set_cache() {
15041         local on=1
15042
15043         if [ "$2" == "off" ]; then
15044                 on=0;
15045         fi
15046         local list=$(comma_list $(osts_nodes))
15047         set_osd_param $list '' $1_cache_enable $on
15048
15049         cancel_lru_locks osc
15050 }
15051
15052 test_151() {
15053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15054         remote_ost_nodsh && skip "remote OST with nodsh"
15055
15056         local CPAGES=3
15057         local list=$(comma_list $(osts_nodes))
15058
15059         # check whether obdfilter is cache capable at all
15060         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15061                 skip "not cache-capable obdfilter"
15062         fi
15063
15064         # check cache is enabled on all obdfilters
15065         if get_osd_param $list '' read_cache_enable | grep 0; then
15066                 skip "oss cache is disabled"
15067         fi
15068
15069         set_osd_param $list '' writethrough_cache_enable 1
15070
15071         # check write cache is enabled on all obdfilters
15072         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15073                 skip "oss write cache is NOT enabled"
15074         fi
15075
15076         roc_hit_init
15077
15078         #define OBD_FAIL_OBD_NO_LRU  0x609
15079         do_nodes $list $LCTL set_param fail_loc=0x609
15080
15081         # pages should be in the case right after write
15082         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15083                 error "dd failed"
15084
15085         local BEFORE=$(roc_hit)
15086         cancel_lru_locks osc
15087         cat $DIR/$tfile >/dev/null
15088         local AFTER=$(roc_hit)
15089
15090         do_nodes $list $LCTL set_param fail_loc=0
15091
15092         if ! let "AFTER - BEFORE == CPAGES"; then
15093                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15094         fi
15095
15096         cancel_lru_locks osc
15097         # invalidates OST cache
15098         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15099         set_osd_param $list '' read_cache_enable 0
15100         cat $DIR/$tfile >/dev/null
15101
15102         # now data shouldn't be found in the cache
15103         BEFORE=$(roc_hit)
15104         cancel_lru_locks osc
15105         cat $DIR/$tfile >/dev/null
15106         AFTER=$(roc_hit)
15107         if let "AFTER - BEFORE != 0"; then
15108                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15109         fi
15110
15111         set_osd_param $list '' read_cache_enable 1
15112         rm -f $DIR/$tfile
15113 }
15114 run_test 151 "test cache on oss and controls ==============================="
15115
15116 test_152() {
15117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15118
15119         local TF="$TMP/$tfile"
15120
15121         # simulate ENOMEM during write
15122 #define OBD_FAIL_OST_NOMEM      0x226
15123         lctl set_param fail_loc=0x80000226
15124         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15125         cp $TF $DIR/$tfile
15126         sync || error "sync failed"
15127         lctl set_param fail_loc=0
15128
15129         # discard client's cache
15130         cancel_lru_locks osc
15131
15132         # simulate ENOMEM during read
15133         lctl set_param fail_loc=0x80000226
15134         cmp $TF $DIR/$tfile || error "cmp failed"
15135         lctl set_param fail_loc=0
15136
15137         rm -f $TF
15138 }
15139 run_test 152 "test read/write with enomem ============================"
15140
15141 test_153() {
15142         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15143 }
15144 run_test 153 "test if fdatasync does not crash ======================="
15145
15146 dot_lustre_fid_permission_check() {
15147         local fid=$1
15148         local ffid=$MOUNT/.lustre/fid/$fid
15149         local test_dir=$2
15150
15151         echo "stat fid $fid"
15152         stat $ffid > /dev/null || error "stat $ffid failed."
15153         echo "touch fid $fid"
15154         touch $ffid || error "touch $ffid failed."
15155         echo "write to fid $fid"
15156         cat /etc/hosts > $ffid || error "write $ffid failed."
15157         echo "read fid $fid"
15158         diff /etc/hosts $ffid || error "read $ffid failed."
15159         echo "append write to fid $fid"
15160         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15161         echo "rename fid $fid"
15162         mv $ffid $test_dir/$tfile.1 &&
15163                 error "rename $ffid to $tfile.1 should fail."
15164         touch $test_dir/$tfile.1
15165         mv $test_dir/$tfile.1 $ffid &&
15166                 error "rename $tfile.1 to $ffid should fail."
15167         rm -f $test_dir/$tfile.1
15168         echo "truncate fid $fid"
15169         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15170         echo "link fid $fid"
15171         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15172         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15173                 echo "setfacl fid $fid"
15174                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15175                 echo "getfacl fid $fid"
15176                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15177         fi
15178         echo "unlink fid $fid"
15179         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15180         echo "mknod fid $fid"
15181         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15182
15183         fid=[0xf00000400:0x1:0x0]
15184         ffid=$MOUNT/.lustre/fid/$fid
15185
15186         echo "stat non-exist fid $fid"
15187         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15188         echo "write to non-exist fid $fid"
15189         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15190         echo "link new fid $fid"
15191         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15192
15193         mkdir -p $test_dir/$tdir
15194         touch $test_dir/$tdir/$tfile
15195         fid=$($LFS path2fid $test_dir/$tdir)
15196         rc=$?
15197         [ $rc -ne 0 ] &&
15198                 error "error: could not get fid for $test_dir/$dir/$tfile."
15199
15200         ffid=$MOUNT/.lustre/fid/$fid
15201
15202         echo "ls $fid"
15203         ls $ffid > /dev/null || error "ls $ffid failed."
15204         echo "touch $fid/$tfile.1"
15205         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15206
15207         echo "touch $MOUNT/.lustre/fid/$tfile"
15208         touch $MOUNT/.lustre/fid/$tfile && \
15209                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15210
15211         echo "setxattr to $MOUNT/.lustre/fid"
15212         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15213
15214         echo "listxattr for $MOUNT/.lustre/fid"
15215         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15216
15217         echo "delxattr from $MOUNT/.lustre/fid"
15218         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15219
15220         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15221         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15222                 error "touch invalid fid should fail."
15223
15224         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15225         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15226                 error "touch non-normal fid should fail."
15227
15228         echo "rename $tdir to $MOUNT/.lustre/fid"
15229         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15230                 error "rename to $MOUNT/.lustre/fid should fail."
15231
15232         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15233         then            # LU-3547
15234                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15235                 local new_obf_mode=777
15236
15237                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15238                 chmod $new_obf_mode $DIR/.lustre/fid ||
15239                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15240
15241                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15242                 [ $obf_mode -eq $new_obf_mode ] ||
15243                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15244
15245                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15246                 chmod $old_obf_mode $DIR/.lustre/fid ||
15247                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15248         fi
15249
15250         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15251         fid=$($LFS path2fid $test_dir/$tfile-2)
15252
15253         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15254         then # LU-5424
15255                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15256                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15257                         error "create lov data thru .lustre failed"
15258         fi
15259         echo "cp /etc/passwd $test_dir/$tfile-2"
15260         cp /etc/passwd $test_dir/$tfile-2 ||
15261                 error "copy to $test_dir/$tfile-2 failed."
15262         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15263         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15264                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15265
15266         rm -rf $test_dir/tfile.lnk
15267         rm -rf $test_dir/$tfile-2
15268 }
15269
15270 test_154A() {
15271         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15272                 skip "Need MDS version at least 2.4.1"
15273
15274         local tf=$DIR/$tfile
15275         touch $tf
15276
15277         local fid=$($LFS path2fid $tf)
15278         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15279
15280         # check that we get the same pathname back
15281         local rootpath
15282         local found
15283         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15284                 echo "$rootpath $fid"
15285                 found=$($LFS fid2path $rootpath "$fid")
15286                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15287                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15288         done
15289
15290         # check wrong root path format
15291         rootpath=$MOUNT"_wrong"
15292         found=$($LFS fid2path $rootpath "$fid")
15293         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15294 }
15295 run_test 154A "lfs path2fid and fid2path basic checks"
15296
15297 test_154B() {
15298         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15299                 skip "Need MDS version at least 2.4.1"
15300
15301         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15302         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15303         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15304         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15305
15306         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15307         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15308
15309         # check that we get the same pathname
15310         echo "PFID: $PFID, name: $name"
15311         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15312         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15313         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15314                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15315
15316         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15317 }
15318 run_test 154B "verify the ll_decode_linkea tool"
15319
15320 test_154a() {
15321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15322         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15323         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15324                 skip "Need MDS version at least 2.2.51"
15325         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15326
15327         cp /etc/hosts $DIR/$tfile
15328
15329         fid=$($LFS path2fid $DIR/$tfile)
15330         rc=$?
15331         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15332
15333         dot_lustre_fid_permission_check "$fid" $DIR ||
15334                 error "dot lustre permission check $fid failed"
15335
15336         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15337
15338         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15339
15340         touch $MOUNT/.lustre/file &&
15341                 error "creation is not allowed under .lustre"
15342
15343         mkdir $MOUNT/.lustre/dir &&
15344                 error "mkdir is not allowed under .lustre"
15345
15346         rm -rf $DIR/$tfile
15347 }
15348 run_test 154a "Open-by-FID"
15349
15350 test_154b() {
15351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15352         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15353         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15354         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15355                 skip "Need MDS version at least 2.2.51"
15356
15357         local remote_dir=$DIR/$tdir/remote_dir
15358         local MDTIDX=1
15359         local rc=0
15360
15361         mkdir -p $DIR/$tdir
15362         $LFS mkdir -i $MDTIDX $remote_dir ||
15363                 error "create remote directory failed"
15364
15365         cp /etc/hosts $remote_dir/$tfile
15366
15367         fid=$($LFS path2fid $remote_dir/$tfile)
15368         rc=$?
15369         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15370
15371         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15372                 error "dot lustre permission check $fid failed"
15373         rm -rf $DIR/$tdir
15374 }
15375 run_test 154b "Open-by-FID for remote directory"
15376
15377 test_154c() {
15378         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15379                 skip "Need MDS version at least 2.4.1"
15380
15381         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15382         local FID1=$($LFS path2fid $DIR/$tfile.1)
15383         local FID2=$($LFS path2fid $DIR/$tfile.2)
15384         local FID3=$($LFS path2fid $DIR/$tfile.3)
15385
15386         local N=1
15387         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15388                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15389                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15390                 local want=FID$N
15391                 [ "$FID" = "${!want}" ] ||
15392                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15393                 N=$((N + 1))
15394         done
15395
15396         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15397         do
15398                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15399                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15400                 N=$((N + 1))
15401         done
15402 }
15403 run_test 154c "lfs path2fid and fid2path multiple arguments"
15404
15405 test_154d() {
15406         remote_mds_nodsh && skip "remote MDS with nodsh"
15407         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15408                 skip "Need MDS version at least 2.5.53"
15409
15410         if remote_mds; then
15411                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15412         else
15413                 nid="0@lo"
15414         fi
15415         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15416         local fd
15417         local cmd
15418
15419         rm -f $DIR/$tfile
15420         touch $DIR/$tfile
15421
15422         local fid=$($LFS path2fid $DIR/$tfile)
15423         # Open the file
15424         fd=$(free_fd)
15425         cmd="exec $fd<$DIR/$tfile"
15426         eval $cmd
15427         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15428         echo "$fid_list" | grep "$fid"
15429         rc=$?
15430
15431         cmd="exec $fd>/dev/null"
15432         eval $cmd
15433         if [ $rc -ne 0 ]; then
15434                 error "FID $fid not found in open files list $fid_list"
15435         fi
15436 }
15437 run_test 154d "Verify open file fid"
15438
15439 test_154e()
15440 {
15441         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15442                 skip "Need MDS version at least 2.6.50"
15443
15444         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15445                 error ".lustre returned by readdir"
15446         fi
15447 }
15448 run_test 154e ".lustre is not returned by readdir"
15449
15450 test_154f() {
15451         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15452
15453         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15454         mkdir_on_mdt0 $DIR/$tdir
15455         # test dirs inherit from its stripe
15456         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15457         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15458         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15459         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15460         touch $DIR/f
15461
15462         # get fid of parents
15463         local FID0=$($LFS path2fid $DIR/$tdir)
15464         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15465         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15466         local FID3=$($LFS path2fid $DIR)
15467
15468         # check that path2fid --parents returns expected <parent_fid>/name
15469         # 1) test for a directory (single parent)
15470         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15471         [ "$parent" == "$FID0/foo1" ] ||
15472                 error "expected parent: $FID0/foo1, got: $parent"
15473
15474         # 2) test for a file with nlink > 1 (multiple parents)
15475         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15476         echo "$parent" | grep -F "$FID1/$tfile" ||
15477                 error "$FID1/$tfile not returned in parent list"
15478         echo "$parent" | grep -F "$FID2/link" ||
15479                 error "$FID2/link not returned in parent list"
15480
15481         # 3) get parent by fid
15482         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15483         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15484         echo "$parent" | grep -F "$FID1/$tfile" ||
15485                 error "$FID1/$tfile not returned in parent list (by fid)"
15486         echo "$parent" | grep -F "$FID2/link" ||
15487                 error "$FID2/link not returned in parent list (by fid)"
15488
15489         # 4) test for entry in root directory
15490         parent=$($LFS path2fid --parents $DIR/f)
15491         echo "$parent" | grep -F "$FID3/f" ||
15492                 error "$FID3/f not returned in parent list"
15493
15494         # 5) test it on root directory
15495         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15496                 error "$MOUNT should not have parents"
15497
15498         # enable xattr caching and check that linkea is correctly updated
15499         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15500         save_lustre_params client "llite.*.xattr_cache" > $save
15501         lctl set_param llite.*.xattr_cache 1
15502
15503         # 6.1) linkea update on rename
15504         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15505
15506         # get parents by fid
15507         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15508         # foo1 should no longer be returned in parent list
15509         echo "$parent" | grep -F "$FID1" &&
15510                 error "$FID1 should no longer be in parent list"
15511         # the new path should appear
15512         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15513                 error "$FID2/$tfile.moved is not in parent list"
15514
15515         # 6.2) linkea update on unlink
15516         rm -f $DIR/$tdir/foo2/link
15517         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15518         # foo2/link should no longer be returned in parent list
15519         echo "$parent" | grep -F "$FID2/link" &&
15520                 error "$FID2/link should no longer be in parent list"
15521         true
15522
15523         rm -f $DIR/f
15524         restore_lustre_params < $save
15525         rm -f $save
15526 }
15527 run_test 154f "get parent fids by reading link ea"
15528
15529 test_154g()
15530 {
15531         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15532         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15533            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15534                 skip "Need MDS version at least 2.6.92"
15535
15536         mkdir_on_mdt0 $DIR/$tdir
15537         llapi_fid_test -d $DIR/$tdir
15538 }
15539 run_test 154g "various llapi FID tests"
15540
15541 test_155_small_load() {
15542     local temp=$TMP/$tfile
15543     local file=$DIR/$tfile
15544
15545     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15546         error "dd of=$temp bs=6096 count=1 failed"
15547     cp $temp $file
15548     cancel_lru_locks $OSC
15549     cmp $temp $file || error "$temp $file differ"
15550
15551     $TRUNCATE $temp 6000
15552     $TRUNCATE $file 6000
15553     cmp $temp $file || error "$temp $file differ (truncate1)"
15554
15555     echo "12345" >>$temp
15556     echo "12345" >>$file
15557     cmp $temp $file || error "$temp $file differ (append1)"
15558
15559     echo "12345" >>$temp
15560     echo "12345" >>$file
15561     cmp $temp $file || error "$temp $file differ (append2)"
15562
15563     rm -f $temp $file
15564     true
15565 }
15566
15567 test_155_big_load() {
15568         remote_ost_nodsh && skip "remote OST with nodsh"
15569
15570         local temp=$TMP/$tfile
15571         local file=$DIR/$tfile
15572
15573         free_min_max
15574         local cache_size=$(do_facet ost$((MAXI+1)) \
15575                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15576         local large_file_size=$((cache_size * 2))
15577
15578         echo "OSS cache size: $cache_size KB"
15579         echo "Large file size: $large_file_size KB"
15580
15581         [ $MAXV -le $large_file_size ] &&
15582                 skip_env "max available OST size needs > $large_file_size KB"
15583
15584         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15585
15586         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15587                 error "dd of=$temp bs=$large_file_size count=1k failed"
15588         cp $temp $file
15589         ls -lh $temp $file
15590         cancel_lru_locks osc
15591         cmp $temp $file || error "$temp $file differ"
15592
15593         rm -f $temp $file
15594         true
15595 }
15596
15597 save_writethrough() {
15598         local facets=$(get_facets OST)
15599
15600         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15601 }
15602
15603 test_155a() {
15604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15605
15606         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15607
15608         save_writethrough $p
15609
15610         set_cache read on
15611         set_cache writethrough on
15612         test_155_small_load
15613         restore_lustre_params < $p
15614         rm -f $p
15615 }
15616 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15617
15618 test_155b() {
15619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15620
15621         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15622
15623         save_writethrough $p
15624
15625         set_cache read on
15626         set_cache writethrough off
15627         test_155_small_load
15628         restore_lustre_params < $p
15629         rm -f $p
15630 }
15631 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15632
15633 test_155c() {
15634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15635
15636         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15637
15638         save_writethrough $p
15639
15640         set_cache read off
15641         set_cache writethrough on
15642         test_155_small_load
15643         restore_lustre_params < $p
15644         rm -f $p
15645 }
15646 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15647
15648 test_155d() {
15649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15650
15651         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15652
15653         save_writethrough $p
15654
15655         set_cache read off
15656         set_cache writethrough off
15657         test_155_small_load
15658         restore_lustre_params < $p
15659         rm -f $p
15660 }
15661 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15662
15663 test_155e() {
15664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15665
15666         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15667
15668         save_writethrough $p
15669
15670         set_cache read on
15671         set_cache writethrough on
15672         test_155_big_load
15673         restore_lustre_params < $p
15674         rm -f $p
15675 }
15676 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15677
15678 test_155f() {
15679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15680
15681         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15682
15683         save_writethrough $p
15684
15685         set_cache read on
15686         set_cache writethrough off
15687         test_155_big_load
15688         restore_lustre_params < $p
15689         rm -f $p
15690 }
15691 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15692
15693 test_155g() {
15694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15695
15696         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15697
15698         save_writethrough $p
15699
15700         set_cache read off
15701         set_cache writethrough on
15702         test_155_big_load
15703         restore_lustre_params < $p
15704         rm -f $p
15705 }
15706 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15707
15708 test_155h() {
15709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15710
15711         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15712
15713         save_writethrough $p
15714
15715         set_cache read off
15716         set_cache writethrough off
15717         test_155_big_load
15718         restore_lustre_params < $p
15719         rm -f $p
15720 }
15721 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15722
15723 test_156() {
15724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15725         remote_ost_nodsh && skip "remote OST with nodsh"
15726         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15727                 skip "stats not implemented on old servers"
15728         [ "$ost1_FSTYPE" = "zfs" ] &&
15729                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15730
15731         local CPAGES=3
15732         local BEFORE
15733         local AFTER
15734         local file="$DIR/$tfile"
15735         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15736
15737         save_writethrough $p
15738         roc_hit_init
15739
15740         log "Turn on read and write cache"
15741         set_cache read on
15742         set_cache writethrough on
15743
15744         log "Write data and read it back."
15745         log "Read should be satisfied from the cache."
15746         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15747         BEFORE=$(roc_hit)
15748         cancel_lru_locks osc
15749         cat $file >/dev/null
15750         AFTER=$(roc_hit)
15751         if ! let "AFTER - BEFORE == CPAGES"; then
15752                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15753         else
15754                 log "cache hits: before: $BEFORE, after: $AFTER"
15755         fi
15756
15757         log "Read again; it should be satisfied from the cache."
15758         BEFORE=$AFTER
15759         cancel_lru_locks osc
15760         cat $file >/dev/null
15761         AFTER=$(roc_hit)
15762         if ! let "AFTER - BEFORE == CPAGES"; then
15763                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15764         else
15765                 log "cache hits:: before: $BEFORE, after: $AFTER"
15766         fi
15767
15768         log "Turn off the read cache and turn on the write cache"
15769         set_cache read off
15770         set_cache writethrough on
15771
15772         log "Read again; it should be satisfied from the cache."
15773         BEFORE=$(roc_hit)
15774         cancel_lru_locks osc
15775         cat $file >/dev/null
15776         AFTER=$(roc_hit)
15777         if ! let "AFTER - BEFORE == CPAGES"; then
15778                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15779         else
15780                 log "cache hits:: before: $BEFORE, after: $AFTER"
15781         fi
15782
15783         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15784                 # > 2.12.56 uses pagecache if cached
15785                 log "Read again; it should not be satisfied from the cache."
15786                 BEFORE=$AFTER
15787                 cancel_lru_locks osc
15788                 cat $file >/dev/null
15789                 AFTER=$(roc_hit)
15790                 if ! let "AFTER - BEFORE == 0"; then
15791                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15792                 else
15793                         log "cache hits:: before: $BEFORE, after: $AFTER"
15794                 fi
15795         fi
15796
15797         log "Write data and read it back."
15798         log "Read should be satisfied from the cache."
15799         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15800         BEFORE=$(roc_hit)
15801         cancel_lru_locks osc
15802         cat $file >/dev/null
15803         AFTER=$(roc_hit)
15804         if ! let "AFTER - BEFORE == CPAGES"; then
15805                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15806         else
15807                 log "cache hits:: before: $BEFORE, after: $AFTER"
15808         fi
15809
15810         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15811                 # > 2.12.56 uses pagecache if cached
15812                 log "Read again; it should not be satisfied from the cache."
15813                 BEFORE=$AFTER
15814                 cancel_lru_locks osc
15815                 cat $file >/dev/null
15816                 AFTER=$(roc_hit)
15817                 if ! let "AFTER - BEFORE == 0"; then
15818                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15819                 else
15820                         log "cache hits:: before: $BEFORE, after: $AFTER"
15821                 fi
15822         fi
15823
15824         log "Turn off read and write cache"
15825         set_cache read off
15826         set_cache writethrough off
15827
15828         log "Write data and read it back"
15829         log "It should not be satisfied from the cache."
15830         rm -f $file
15831         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15832         cancel_lru_locks osc
15833         BEFORE=$(roc_hit)
15834         cat $file >/dev/null
15835         AFTER=$(roc_hit)
15836         if ! let "AFTER - BEFORE == 0"; then
15837                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15838         else
15839                 log "cache hits:: before: $BEFORE, after: $AFTER"
15840         fi
15841
15842         log "Turn on the read cache and turn off the write cache"
15843         set_cache read on
15844         set_cache writethrough off
15845
15846         log "Write data and read it back"
15847         log "It should not be satisfied from the cache."
15848         rm -f $file
15849         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15850         BEFORE=$(roc_hit)
15851         cancel_lru_locks osc
15852         cat $file >/dev/null
15853         AFTER=$(roc_hit)
15854         if ! let "AFTER - BEFORE == 0"; then
15855                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15856         else
15857                 log "cache hits:: before: $BEFORE, after: $AFTER"
15858         fi
15859
15860         log "Read again; it should be satisfied from the cache."
15861         BEFORE=$(roc_hit)
15862         cancel_lru_locks osc
15863         cat $file >/dev/null
15864         AFTER=$(roc_hit)
15865         if ! let "AFTER - BEFORE == CPAGES"; then
15866                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15867         else
15868                 log "cache hits:: before: $BEFORE, after: $AFTER"
15869         fi
15870
15871         restore_lustre_params < $p
15872         rm -f $p $file
15873 }
15874 run_test 156 "Verification of tunables"
15875
15876 test_160a() {
15877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15878         remote_mds_nodsh && skip "remote MDS with nodsh"
15879         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15880                 skip "Need MDS version at least 2.2.0"
15881
15882         changelog_register || error "changelog_register failed"
15883         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15884         changelog_users $SINGLEMDS | grep -q $cl_user ||
15885                 error "User $cl_user not found in changelog_users"
15886
15887         mkdir_on_mdt0 $DIR/$tdir
15888
15889         # change something
15890         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15891         changelog_clear 0 || error "changelog_clear failed"
15892         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15893         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15894         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15895         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15896         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15897         rm $DIR/$tdir/pics/desktop.jpg
15898
15899         echo "verifying changelog mask"
15900         changelog_chmask "-MKDIR"
15901         changelog_chmask "-CLOSE"
15902
15903         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15904         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15905
15906         changelog_chmask "+MKDIR"
15907         changelog_chmask "+CLOSE"
15908
15909         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15910         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15911
15912         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15913         CLOSES=$(changelog_dump | grep -c "CLOSE")
15914         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15915         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15916
15917         # verify contents
15918         echo "verifying target fid"
15919         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15920         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15921         [ "$fidc" == "$fidf" ] ||
15922                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15923         echo "verifying parent fid"
15924         # The FID returned from the Changelog may be the directory shard on
15925         # a different MDT, and not the FID returned by path2fid on the parent.
15926         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15927         # since this is what will matter when recreating this file in the tree.
15928         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15929         local pathp=$($LFS fid2path $MOUNT "$fidp")
15930         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15931                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15932
15933         echo "getting records for $cl_user"
15934         changelog_users $SINGLEMDS
15935         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15936         local nclr=3
15937         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15938                 error "changelog_clear failed"
15939         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15940         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15941         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15942                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15943
15944         local min0_rec=$(changelog_users $SINGLEMDS |
15945                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15946         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15947                           awk '{ print $1; exit; }')
15948
15949         changelog_dump | tail -n 5
15950         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15951         [ $first_rec == $((min0_rec + 1)) ] ||
15952                 error "first index should be $min0_rec + 1 not $first_rec"
15953
15954         # LU-3446 changelog index reset on MDT restart
15955         local cur_rec1=$(changelog_users $SINGLEMDS |
15956                          awk '/^current.index:/ { print $NF }')
15957         changelog_clear 0 ||
15958                 error "clear all changelog records for $cl_user failed"
15959         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15960         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15961                 error "Fail to start $SINGLEMDS"
15962         local cur_rec2=$(changelog_users $SINGLEMDS |
15963                          awk '/^current.index:/ { print $NF }')
15964         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15965         [ $cur_rec1 == $cur_rec2 ] ||
15966                 error "current index should be $cur_rec1 not $cur_rec2"
15967
15968         echo "verifying users from this test are deregistered"
15969         changelog_deregister || error "changelog_deregister failed"
15970         changelog_users $SINGLEMDS | grep -q $cl_user &&
15971                 error "User '$cl_user' still in changelog_users"
15972
15973         # lctl get_param -n mdd.*.changelog_users
15974         # current_index: 144
15975         # ID    index (idle seconds)
15976         # cl3   144   (2) mask=<list>
15977         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15978                 # this is the normal case where all users were deregistered
15979                 # make sure no new records are added when no users are present
15980                 local last_rec1=$(changelog_users $SINGLEMDS |
15981                                   awk '/^current.index:/ { print $NF }')
15982                 touch $DIR/$tdir/chloe
15983                 local last_rec2=$(changelog_users $SINGLEMDS |
15984                                   awk '/^current.index:/ { print $NF }')
15985                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15986                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15987         else
15988                 # any changelog users must be leftovers from a previous test
15989                 changelog_users $SINGLEMDS
15990                 echo "other changelog users; can't verify off"
15991         fi
15992 }
15993 run_test 160a "changelog sanity"
15994
15995 test_160b() { # LU-3587
15996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15997         remote_mds_nodsh && skip "remote MDS with nodsh"
15998         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15999                 skip "Need MDS version at least 2.2.0"
16000
16001         changelog_register || error "changelog_register failed"
16002         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16003         changelog_users $SINGLEMDS | grep -q $cl_user ||
16004                 error "User '$cl_user' not found in changelog_users"
16005
16006         local longname1=$(str_repeat a 255)
16007         local longname2=$(str_repeat b 255)
16008
16009         cd $DIR
16010         echo "creating very long named file"
16011         touch $longname1 || error "create of '$longname1' failed"
16012         echo "renaming very long named file"
16013         mv $longname1 $longname2
16014
16015         changelog_dump | grep RENME | tail -n 5
16016         rm -f $longname2
16017 }
16018 run_test 160b "Verify that very long rename doesn't crash in changelog"
16019
16020 test_160c() {
16021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16022         remote_mds_nodsh && skip "remote MDS with nodsh"
16023
16024         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16025                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16026                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16027                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16028
16029         local rc=0
16030
16031         # Registration step
16032         changelog_register || error "changelog_register failed"
16033
16034         rm -rf $DIR/$tdir
16035         mkdir -p $DIR/$tdir
16036         $MCREATE $DIR/$tdir/foo_160c
16037         changelog_chmask "-TRUNC"
16038         $TRUNCATE $DIR/$tdir/foo_160c 200
16039         changelog_chmask "+TRUNC"
16040         $TRUNCATE $DIR/$tdir/foo_160c 199
16041         changelog_dump | tail -n 5
16042         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16043         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16044 }
16045 run_test 160c "verify that changelog log catch the truncate event"
16046
16047 test_160d() {
16048         remote_mds_nodsh && skip "remote MDS with nodsh"
16049         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16051         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16052                 skip "Need MDS version at least 2.7.60"
16053
16054         # Registration step
16055         changelog_register || error "changelog_register failed"
16056
16057         mkdir -p $DIR/$tdir/migrate_dir
16058         changelog_clear 0 || error "changelog_clear failed"
16059
16060         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16061         changelog_dump | tail -n 5
16062         local migrates=$(changelog_dump | grep -c "MIGRT")
16063         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16064 }
16065 run_test 160d "verify that changelog log catch the migrate event"
16066
16067 test_160e() {
16068         remote_mds_nodsh && skip "remote MDS with nodsh"
16069
16070         # Create a user
16071         changelog_register || error "changelog_register failed"
16072
16073         local MDT0=$(facet_svc $SINGLEMDS)
16074         local rc
16075
16076         # No user (expect fail)
16077         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16078         rc=$?
16079         if [ $rc -eq 0 ]; then
16080                 error "Should fail without user"
16081         elif [ $rc -ne 4 ]; then
16082                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16083         fi
16084
16085         # Delete a future user (expect fail)
16086         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16087         rc=$?
16088         if [ $rc -eq 0 ]; then
16089                 error "Deleted non-existant user cl77"
16090         elif [ $rc -ne 2 ]; then
16091                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16092         fi
16093
16094         # Clear to a bad index (1 billion should be safe)
16095         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16096         rc=$?
16097
16098         if [ $rc -eq 0 ]; then
16099                 error "Successfully cleared to invalid CL index"
16100         elif [ $rc -ne 22 ]; then
16101                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16102         fi
16103 }
16104 run_test 160e "changelog negative testing (should return errors)"
16105
16106 test_160f() {
16107         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16108         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16109                 skip "Need MDS version at least 2.10.56"
16110
16111         local mdts=$(comma_list $(mdts_nodes))
16112
16113         # Create a user
16114         changelog_register || error "first changelog_register failed"
16115         changelog_register || error "second changelog_register failed"
16116         local cl_users
16117         declare -A cl_user1
16118         declare -A cl_user2
16119         local user_rec1
16120         local user_rec2
16121         local i
16122
16123         # generate some changelog records to accumulate on each MDT
16124         # use all_char because created files should be evenly distributed
16125         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16126                 error "test_mkdir $tdir failed"
16127         log "$(date +%s): creating first files"
16128         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16129                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16130                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16131         done
16132
16133         # check changelogs have been generated
16134         local start=$SECONDS
16135         local idle_time=$((MDSCOUNT * 5 + 5))
16136         local nbcl=$(changelog_dump | wc -l)
16137         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16138
16139         for param in "changelog_max_idle_time=$idle_time" \
16140                      "changelog_gc=1" \
16141                      "changelog_min_gc_interval=2" \
16142                      "changelog_min_free_cat_entries=3"; do
16143                 local MDT0=$(facet_svc $SINGLEMDS)
16144                 local var="${param%=*}"
16145                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16146
16147                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16148                 do_nodes $mdts $LCTL set_param mdd.*.$param
16149         done
16150
16151         # force cl_user2 to be idle (1st part), but also cancel the
16152         # cl_user1 records so that it is not evicted later in the test.
16153         local sleep1=$((idle_time / 2))
16154         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16155         sleep $sleep1
16156
16157         # simulate changelog catalog almost full
16158         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16159         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16160
16161         for i in $(seq $MDSCOUNT); do
16162                 cl_users=(${CL_USERS[mds$i]})
16163                 cl_user1[mds$i]="${cl_users[0]}"
16164                 cl_user2[mds$i]="${cl_users[1]}"
16165
16166                 [ -n "${cl_user1[mds$i]}" ] ||
16167                         error "mds$i: no user registered"
16168                 [ -n "${cl_user2[mds$i]}" ] ||
16169                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16170
16171                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16172                 [ -n "$user_rec1" ] ||
16173                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16174                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16175                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16176                 [ -n "$user_rec2" ] ||
16177                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16178                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16179                      "$user_rec1 + 2 == $user_rec2"
16180                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16181                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16182                               "$user_rec1 + 2, but is $user_rec2"
16183                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16184                 [ -n "$user_rec2" ] ||
16185                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16186                 [ $user_rec1 == $user_rec2 ] ||
16187                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16188                               "$user_rec1, but is $user_rec2"
16189         done
16190
16191         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16192         local sleep2=$((idle_time - (SECONDS - start) + 1))
16193         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16194         sleep $sleep2
16195
16196         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16197         # cl_user1 should be OK because it recently processed records.
16198         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16199         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16200                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16201                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16202         done
16203
16204         # ensure gc thread is done
16205         for i in $(mdts_nodes); do
16206                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16207                         error "$i: GC-thread not done"
16208         done
16209
16210         local first_rec
16211         for (( i = 1; i <= MDSCOUNT; i++ )); do
16212                 # check cl_user1 still registered
16213                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16214                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16215                 # check cl_user2 unregistered
16216                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16217                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16218
16219                 # check changelogs are present and starting at $user_rec1 + 1
16220                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16221                 [ -n "$user_rec1" ] ||
16222                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16223                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16224                             awk '{ print $1; exit; }')
16225
16226                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16227                 [ $((user_rec1 + 1)) == $first_rec ] ||
16228                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16229         done
16230 }
16231 run_test 160f "changelog garbage collect (timestamped users)"
16232
16233 test_160g() {
16234         remote_mds_nodsh && skip "remote MDS with nodsh"
16235         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16236                 skip "Need MDS version at least 2.14.55"
16237
16238         local mdts=$(comma_list $(mdts_nodes))
16239
16240         # Create a user
16241         changelog_register || error "first changelog_register failed"
16242         changelog_register || error "second changelog_register failed"
16243         local cl_users
16244         declare -A cl_user1
16245         declare -A cl_user2
16246         local user_rec1
16247         local user_rec2
16248         local i
16249
16250         # generate some changelog records to accumulate on each MDT
16251         # use all_char because created files should be evenly distributed
16252         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16253                 error "test_mkdir $tdir failed"
16254         for ((i = 0; i < MDSCOUNT; i++)); do
16255                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16256                         error "create $DIR/$tdir/d$i.1 failed"
16257         done
16258
16259         # check changelogs have been generated
16260         local nbcl=$(changelog_dump | wc -l)
16261         (( $nbcl > 0 )) || error "no changelogs found"
16262
16263         # reduce the max_idle_indexes value to make sure we exceed it
16264         for param in "changelog_max_idle_indexes=2" \
16265                      "changelog_gc=1" \
16266                      "changelog_min_gc_interval=2"; do
16267                 local MDT0=$(facet_svc $SINGLEMDS)
16268                 local var="${param%=*}"
16269                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16270
16271                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16272                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16273                         error "unable to set mdd.*.$param"
16274         done
16275
16276         local start=$SECONDS
16277         for i in $(seq $MDSCOUNT); do
16278                 cl_users=(${CL_USERS[mds$i]})
16279                 cl_user1[mds$i]="${cl_users[0]}"
16280                 cl_user2[mds$i]="${cl_users[1]}"
16281
16282                 [ -n "${cl_user1[mds$i]}" ] ||
16283                         error "mds$i: user1 is not registered"
16284                 [ -n "${cl_user2[mds$i]}" ] ||
16285                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16286
16287                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16288                 [ -n "$user_rec1" ] ||
16289                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16290                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16291                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16292                 [ -n "$user_rec2" ] ||
16293                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16294                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16295                      "$user_rec1 + 2 == $user_rec2"
16296                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16297                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16298                               "expected $user_rec1 + 2, but is $user_rec2"
16299                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16300                 [ -n "$user_rec2" ] ||
16301                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16302                 [ $user_rec1 == $user_rec2 ] ||
16303                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16304                               "expected $user_rec1, but is $user_rec2"
16305         done
16306
16307         # ensure we are past the previous changelog_min_gc_interval set above
16308         local sleep2=$((start + 2 - SECONDS))
16309         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16310         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16311         # cl_user1 should be OK because it recently processed records.
16312         for ((i = 0; i < MDSCOUNT; i++)); do
16313                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16314                         error "create $DIR/$tdir/d$i.3 failed"
16315         done
16316
16317         # ensure gc thread is done
16318         for i in $(mdts_nodes); do
16319                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16320                         error "$i: GC-thread not done"
16321         done
16322
16323         local first_rec
16324         for (( i = 1; i <= MDSCOUNT; i++ )); do
16325                 # check cl_user1 still registered
16326                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16327                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16328                 # check cl_user2 unregistered
16329                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16330                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16331
16332                 # check changelogs are present and starting at $user_rec1 + 1
16333                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16334                 [ -n "$user_rec1" ] ||
16335                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16336                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16337                             awk '{ print $1; exit; }')
16338
16339                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16340                 [ $((user_rec1 + 1)) == $first_rec ] ||
16341                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16342         done
16343 }
16344 run_test 160g "changelog garbage collect on idle records"
16345
16346 test_160h() {
16347         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16348         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16349                 skip "Need MDS version at least 2.10.56"
16350
16351         local mdts=$(comma_list $(mdts_nodes))
16352
16353         # Create a user
16354         changelog_register || error "first changelog_register failed"
16355         changelog_register || error "second changelog_register failed"
16356         local cl_users
16357         declare -A cl_user1
16358         declare -A cl_user2
16359         local user_rec1
16360         local user_rec2
16361         local i
16362
16363         # generate some changelog records to accumulate on each MDT
16364         # use all_char because created files should be evenly distributed
16365         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16366                 error "test_mkdir $tdir failed"
16367         for ((i = 0; i < MDSCOUNT; i++)); do
16368                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16369                         error "create $DIR/$tdir/d$i.1 failed"
16370         done
16371
16372         # check changelogs have been generated
16373         local nbcl=$(changelog_dump | wc -l)
16374         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16375
16376         for param in "changelog_max_idle_time=10" \
16377                      "changelog_gc=1" \
16378                      "changelog_min_gc_interval=2"; do
16379                 local MDT0=$(facet_svc $SINGLEMDS)
16380                 local var="${param%=*}"
16381                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16382
16383                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16384                 do_nodes $mdts $LCTL set_param mdd.*.$param
16385         done
16386
16387         # force cl_user2 to be idle (1st part)
16388         sleep 9
16389
16390         for i in $(seq $MDSCOUNT); do
16391                 cl_users=(${CL_USERS[mds$i]})
16392                 cl_user1[mds$i]="${cl_users[0]}"
16393                 cl_user2[mds$i]="${cl_users[1]}"
16394
16395                 [ -n "${cl_user1[mds$i]}" ] ||
16396                         error "mds$i: no user registered"
16397                 [ -n "${cl_user2[mds$i]}" ] ||
16398                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16399
16400                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16401                 [ -n "$user_rec1" ] ||
16402                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16403                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16404                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16405                 [ -n "$user_rec2" ] ||
16406                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16407                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16408                      "$user_rec1 + 2 == $user_rec2"
16409                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16410                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16411                               "$user_rec1 + 2, but is $user_rec2"
16412                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16413                 [ -n "$user_rec2" ] ||
16414                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16415                 [ $user_rec1 == $user_rec2 ] ||
16416                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16417                               "$user_rec1, but is $user_rec2"
16418         done
16419
16420         # force cl_user2 to be idle (2nd part) and to reach
16421         # changelog_max_idle_time
16422         sleep 2
16423
16424         # force each GC-thread start and block then
16425         # one per MDT/MDD, set fail_val accordingly
16426         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16427         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16428
16429         # generate more changelogs to trigger fail_loc
16430         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16431                 error "create $DIR/$tdir/${tfile}bis failed"
16432
16433         # stop MDT to stop GC-thread, should be done in back-ground as it will
16434         # block waiting for the thread to be released and exit
16435         declare -A stop_pids
16436         for i in $(seq $MDSCOUNT); do
16437                 stop mds$i &
16438                 stop_pids[mds$i]=$!
16439         done
16440
16441         for i in $(mdts_nodes); do
16442                 local facet
16443                 local nb=0
16444                 local facets=$(facets_up_on_host $i)
16445
16446                 for facet in ${facets//,/ }; do
16447                         if [[ $facet == mds* ]]; then
16448                                 nb=$((nb + 1))
16449                         fi
16450                 done
16451                 # ensure each MDS's gc threads are still present and all in "R"
16452                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16453                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16454                         error "$i: expected $nb GC-thread"
16455                 wait_update $i \
16456                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16457                         "R" 20 ||
16458                         error "$i: GC-thread not found in R-state"
16459                 # check umounts of each MDT on MDS have reached kthread_stop()
16460                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16461                         error "$i: expected $nb umount"
16462                 wait_update $i \
16463                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16464                         error "$i: umount not found in D-state"
16465         done
16466
16467         # release all GC-threads
16468         do_nodes $mdts $LCTL set_param fail_loc=0
16469
16470         # wait for MDT stop to complete
16471         for i in $(seq $MDSCOUNT); do
16472                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16473         done
16474
16475         # XXX
16476         # may try to check if any orphan changelog records are present
16477         # via ldiskfs/zfs and llog_reader...
16478
16479         # re-start/mount MDTs
16480         for i in $(seq $MDSCOUNT); do
16481                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16482                         error "Fail to start mds$i"
16483         done
16484
16485         local first_rec
16486         for i in $(seq $MDSCOUNT); do
16487                 # check cl_user1 still registered
16488                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16489                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16490                 # check cl_user2 unregistered
16491                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16492                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16493
16494                 # check changelogs are present and starting at $user_rec1 + 1
16495                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16496                 [ -n "$user_rec1" ] ||
16497                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16498                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16499                             awk '{ print $1; exit; }')
16500
16501                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16502                 [ $((user_rec1 + 1)) == $first_rec ] ||
16503                         error "mds$i: first index should be $user_rec1 + 1, " \
16504                               "but is $first_rec"
16505         done
16506 }
16507 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16508               "during mount"
16509
16510 test_160i() {
16511
16512         local mdts=$(comma_list $(mdts_nodes))
16513
16514         changelog_register || error "first changelog_register failed"
16515
16516         # generate some changelog records to accumulate on each MDT
16517         # use all_char because created files should be evenly distributed
16518         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16519                 error "test_mkdir $tdir failed"
16520         for ((i = 0; i < MDSCOUNT; i++)); do
16521                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16522                         error "create $DIR/$tdir/d$i.1 failed"
16523         done
16524
16525         # check changelogs have been generated
16526         local nbcl=$(changelog_dump | wc -l)
16527         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16528
16529         # simulate race between register and unregister
16530         # XXX as fail_loc is set per-MDS, with DNE configs the race
16531         # simulation will only occur for one MDT per MDS and for the
16532         # others the normal race scenario will take place
16533         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16534         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16535         do_nodes $mdts $LCTL set_param fail_val=1
16536
16537         # unregister 1st user
16538         changelog_deregister &
16539         local pid1=$!
16540         # wait some time for deregister work to reach race rdv
16541         sleep 2
16542         # register 2nd user
16543         changelog_register || error "2nd user register failed"
16544
16545         wait $pid1 || error "1st user deregister failed"
16546
16547         local i
16548         local last_rec
16549         declare -A LAST_REC
16550         for i in $(seq $MDSCOUNT); do
16551                 if changelog_users mds$i | grep "^cl"; then
16552                         # make sure new records are added with one user present
16553                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16554                                           awk '/^current.index:/ { print $NF }')
16555                 else
16556                         error "mds$i has no user registered"
16557                 fi
16558         done
16559
16560         # generate more changelog records to accumulate on each MDT
16561         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16562                 error "create $DIR/$tdir/${tfile}bis failed"
16563
16564         for i in $(seq $MDSCOUNT); do
16565                 last_rec=$(changelog_users $SINGLEMDS |
16566                            awk '/^current.index:/ { print $NF }')
16567                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16568                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16569                         error "changelogs are off on mds$i"
16570         done
16571 }
16572 run_test 160i "changelog user register/unregister race"
16573
16574 test_160j() {
16575         remote_mds_nodsh && skip "remote MDS with nodsh"
16576         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16577                 skip "Need MDS version at least 2.12.56"
16578
16579         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16580         stack_trap "umount $MOUNT2" EXIT
16581
16582         changelog_register || error "first changelog_register failed"
16583         stack_trap "changelog_deregister" EXIT
16584
16585         # generate some changelog
16586         # use all_char because created files should be evenly distributed
16587         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16588                 error "mkdir $tdir failed"
16589         for ((i = 0; i < MDSCOUNT; i++)); do
16590                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16591                         error "create $DIR/$tdir/d$i.1 failed"
16592         done
16593
16594         # open the changelog device
16595         exec 3>/dev/changelog-$FSNAME-MDT0000
16596         stack_trap "exec 3>&-" EXIT
16597         exec 4</dev/changelog-$FSNAME-MDT0000
16598         stack_trap "exec 4<&-" EXIT
16599
16600         # umount the first lustre mount
16601         umount $MOUNT
16602         stack_trap "mount_client $MOUNT" EXIT
16603
16604         # read changelog, which may or may not fail, but should not crash
16605         cat <&4 >/dev/null
16606
16607         # clear changelog
16608         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16609         changelog_users $SINGLEMDS | grep -q $cl_user ||
16610                 error "User $cl_user not found in changelog_users"
16611
16612         printf 'clear:'$cl_user':0' >&3
16613 }
16614 run_test 160j "client can be umounted while its chanangelog is being used"
16615
16616 test_160k() {
16617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16618         remote_mds_nodsh && skip "remote MDS with nodsh"
16619
16620         mkdir -p $DIR/$tdir/1/1
16621
16622         changelog_register || error "changelog_register failed"
16623         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16624
16625         changelog_users $SINGLEMDS | grep -q $cl_user ||
16626                 error "User '$cl_user' not found in changelog_users"
16627 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16628         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16629         rmdir $DIR/$tdir/1/1 & sleep 1
16630         mkdir $DIR/$tdir/2
16631         touch $DIR/$tdir/2/2
16632         rm -rf $DIR/$tdir/2
16633
16634         wait
16635         sleep 4
16636
16637         changelog_dump | grep rmdir || error "rmdir not recorded"
16638 }
16639 run_test 160k "Verify that changelog records are not lost"
16640
16641 # Verifies that a file passed as a parameter has recently had an operation
16642 # performed on it that has generated an MTIME changelog which contains the
16643 # correct parent FID. As files might reside on a different MDT from the
16644 # parent directory in DNE configurations, the FIDs are translated to paths
16645 # before being compared, which should be identical
16646 compare_mtime_changelog() {
16647         local file="${1}"
16648         local mdtidx
16649         local mtime
16650         local cl_fid
16651         local pdir
16652         local dir
16653
16654         mdtidx=$($LFS getstripe --mdt-index $file)
16655         mdtidx=$(printf "%04x" $mdtidx)
16656
16657         # Obtain the parent FID from the MTIME changelog
16658         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16659         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16660
16661         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16662         [ -z "$cl_fid" ] && error "parent FID not present"
16663
16664         # Verify that the path for the parent FID is the same as the path for
16665         # the test directory
16666         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16667
16668         dir=$(dirname $1)
16669
16670         [[ "${pdir%/}" == "$dir" ]] ||
16671                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16672 }
16673
16674 test_160l() {
16675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16676
16677         remote_mds_nodsh && skip "remote MDS with nodsh"
16678         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16679                 skip "Need MDS version at least 2.13.55"
16680
16681         local cl_user
16682
16683         changelog_register || error "changelog_register failed"
16684         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16685
16686         changelog_users $SINGLEMDS | grep -q $cl_user ||
16687                 error "User '$cl_user' not found in changelog_users"
16688
16689         # Clear some types so that MTIME changelogs are generated
16690         changelog_chmask "-CREAT"
16691         changelog_chmask "-CLOSE"
16692
16693         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16694
16695         # Test CL_MTIME during setattr
16696         touch $DIR/$tdir/$tfile
16697         compare_mtime_changelog $DIR/$tdir/$tfile
16698
16699         # Test CL_MTIME during close
16700         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16701         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16702 }
16703 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16704
16705 test_160m() {
16706         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16707         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16708                 skip "Need MDS version at least 2.14.51"
16709         local cl_users
16710         local cl_user1
16711         local cl_user2
16712         local pid1
16713
16714         # Create a user
16715         changelog_register || error "first changelog_register failed"
16716         changelog_register || error "second changelog_register failed"
16717
16718         cl_users=(${CL_USERS[mds1]})
16719         cl_user1="${cl_users[0]}"
16720         cl_user2="${cl_users[1]}"
16721         # generate some changelog records to accumulate on MDT0
16722         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16723         createmany -m $DIR/$tdir/$tfile 50 ||
16724                 error "create $DIR/$tdir/$tfile failed"
16725         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16726         rm -f $DIR/$tdir
16727
16728         # check changelogs have been generated
16729         local nbcl=$(changelog_dump | wc -l)
16730         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16731
16732 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16733         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16734
16735         __changelog_clear mds1 $cl_user1 +10
16736         __changelog_clear mds1 $cl_user2 0 &
16737         pid1=$!
16738         sleep 2
16739         __changelog_clear mds1 $cl_user1 0 ||
16740                 error "fail to cancel record for $cl_user1"
16741         wait $pid1
16742         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16743 }
16744 run_test 160m "Changelog clear race"
16745
16746 test_160n() {
16747         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16748         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16749                 skip "Need MDS version at least 2.14.51"
16750         local cl_users
16751         local cl_user1
16752         local cl_user2
16753         local pid1
16754         local first_rec
16755         local last_rec=0
16756
16757         # Create a user
16758         changelog_register || error "first changelog_register failed"
16759
16760         cl_users=(${CL_USERS[mds1]})
16761         cl_user1="${cl_users[0]}"
16762
16763         # generate some changelog records to accumulate on MDT0
16764         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16765         first_rec=$(changelog_users $SINGLEMDS |
16766                         awk '/^current.index:/ { print $NF }')
16767         while (( last_rec < (( first_rec + 65000)) )); do
16768                 createmany -m $DIR/$tdir/$tfile 10000 ||
16769                         error "create $DIR/$tdir/$tfile failed"
16770
16771                 for i in $(seq 0 10000); do
16772                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16773                                 > /dev/null
16774                 done
16775
16776                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16777                         error "unlinkmany failed unlink"
16778                 last_rec=$(changelog_users $SINGLEMDS |
16779                         awk '/^current.index:/ { print $NF }')
16780                 echo last record $last_rec
16781                 (( last_rec == 0 )) && error "no changelog found"
16782         done
16783
16784 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16785         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16786
16787         __changelog_clear mds1 $cl_user1 0 &
16788         pid1=$!
16789         sleep 2
16790         __changelog_clear mds1 $cl_user1 0 ||
16791                 error "fail to cancel record for $cl_user1"
16792         wait $pid1
16793         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16794 }
16795 run_test 160n "Changelog destroy race"
16796
16797 test_160o() {
16798         local mdt="$(facet_svc $SINGLEMDS)"
16799
16800         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16801         remote_mds_nodsh && skip "remote MDS with nodsh"
16802         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16803                 skip "Need MDS version at least 2.14.52"
16804
16805         changelog_register --user test_160o -m unlnk+close+open ||
16806                 error "changelog_register failed"
16807
16808         do_facet $SINGLEMDS $LCTL --device $mdt \
16809                                 changelog_register -u "Tt3_-#" &&
16810                 error "bad symbols in name should fail"
16811
16812         do_facet $SINGLEMDS $LCTL --device $mdt \
16813                                 changelog_register -u test_160o &&
16814                 error "the same name registration should fail"
16815
16816         do_facet $SINGLEMDS $LCTL --device $mdt \
16817                         changelog_register -u test_160toolongname &&
16818                 error "too long name registration should fail"
16819
16820         changelog_chmask "MARK+HSM"
16821         lctl get_param mdd.*.changelog*mask
16822         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16823         changelog_users $SINGLEMDS | grep -q $cl_user ||
16824                 error "User $cl_user not found in changelog_users"
16825         #verify username
16826         echo $cl_user | grep -q test_160o ||
16827                 error "User $cl_user has no specific name 'test160o'"
16828
16829         # change something
16830         changelog_clear 0 || error "changelog_clear failed"
16831         # generate some changelog records to accumulate on MDT0
16832         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16833         touch $DIR/$tdir/$tfile                 # open 1
16834
16835         OPENS=$(changelog_dump | grep -c "OPEN")
16836         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16837
16838         # must be no MKDIR it wasn't set as user mask
16839         MKDIR=$(changelog_dump | grep -c "MKDIR")
16840         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16841
16842         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16843                                 mdd.$mdt.changelog_current_mask -n)
16844         # register maskless user
16845         changelog_register || error "changelog_register failed"
16846         # effective mask should be not changed because it is not minimal
16847         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16848                                 mdd.$mdt.changelog_current_mask -n)
16849         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16850         # set server mask to minimal value
16851         changelog_chmask "MARK"
16852         # check effective mask again, should be treated as DEFMASK now
16853         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16854                                 mdd.$mdt.changelog_current_mask -n)
16855         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16856
16857         do_facet $SINGLEMDS $LCTL --device $mdt \
16858                                 changelog_deregister -u test_160o ||
16859                 error "cannot deregister by name"
16860 }
16861 run_test 160o "changelog user name and mask"
16862
16863 test_160p() {
16864         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16865         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16866                 skip "Need MDS version at least 2.14.51"
16867         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16868         local cl_users
16869         local cl_user1
16870         local entry_count
16871
16872         # Create a user
16873         changelog_register || error "first changelog_register failed"
16874
16875         cl_users=(${CL_USERS[mds1]})
16876         cl_user1="${cl_users[0]}"
16877
16878         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16879         createmany -m $DIR/$tdir/$tfile 50 ||
16880                 error "create $DIR/$tdir/$tfile failed"
16881         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16882         rm -rf $DIR/$tdir
16883
16884         # check changelogs have been generated
16885         entry_count=$(changelog_dump | wc -l)
16886         ((entry_count != 0)) || error "no changelog entries found"
16887
16888         # remove changelog_users and check that orphan entries are removed
16889         stop mds1
16890         local dev=$(mdsdevname 1)
16891         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16892         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16893         entry_count=$(changelog_dump | wc -l)
16894         ((entry_count == 0)) ||
16895                 error "found $entry_count changelog entries, expected none"
16896 }
16897 run_test 160p "Changelog orphan cleanup with no users"
16898
16899 test_160q() {
16900         local mdt="$(facet_svc $SINGLEMDS)"
16901         local clu
16902
16903         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16904         remote_mds_nodsh && skip "remote MDS with nodsh"
16905         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16906                 skip "Need MDS version at least 2.14.54"
16907
16908         # set server mask to minimal value like server init does
16909         changelog_chmask "MARK"
16910         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16911                 error "changelog_register failed"
16912         # check effective mask again, should be treated as DEFMASK now
16913         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16914                                 mdd.$mdt.changelog_current_mask -n)
16915         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16916                 error "changelog_deregister failed"
16917         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16918 }
16919 run_test 160q "changelog effective mask is DEFMASK if not set"
16920
16921 test_160s() {
16922         remote_mds_nodsh && skip "remote MDS with nodsh"
16923         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16924                 skip "Need MDS version at least 2.14.55"
16925
16926         local mdts=$(comma_list $(mdts_nodes))
16927
16928         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16929         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16930                                        fail_val=$((24 * 3600 * 10))
16931
16932         # Create a user which is 10 days old
16933         changelog_register || error "first changelog_register failed"
16934         local cl_users
16935         declare -A cl_user1
16936         local i
16937
16938         # generate some changelog records to accumulate on each MDT
16939         # use all_char because created files should be evenly distributed
16940         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16941                 error "test_mkdir $tdir failed"
16942         for ((i = 0; i < MDSCOUNT; i++)); do
16943                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16944                         error "create $DIR/$tdir/d$i.1 failed"
16945         done
16946
16947         # check changelogs have been generated
16948         local nbcl=$(changelog_dump | wc -l)
16949         (( nbcl > 0 )) || error "no changelogs found"
16950
16951         # reduce the max_idle_indexes value to make sure we exceed it
16952         for param in "changelog_max_idle_indexes=2097446912" \
16953                      "changelog_max_idle_time=2592000" \
16954                      "changelog_gc=1" \
16955                      "changelog_min_gc_interval=2"; do
16956                 local MDT0=$(facet_svc $SINGLEMDS)
16957                 local var="${param%=*}"
16958                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16959
16960                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16961                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16962                         error "unable to set mdd.*.$param"
16963         done
16964
16965         local start=$SECONDS
16966         for i in $(seq $MDSCOUNT); do
16967                 cl_users=(${CL_USERS[mds$i]})
16968                 cl_user1[mds$i]="${cl_users[0]}"
16969
16970                 [[ -n "${cl_user1[mds$i]}" ]] ||
16971                         error "mds$i: no user registered"
16972         done
16973
16974         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16975         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16976
16977         # ensure we are past the previous changelog_min_gc_interval set above
16978         local sleep2=$((start + 2 - SECONDS))
16979         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16980
16981         # Generate one more changelog to trigger GC
16982         for ((i = 0; i < MDSCOUNT; i++)); do
16983                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16984                         error "create $DIR/$tdir/d$i.3 failed"
16985         done
16986
16987         # ensure gc thread is done
16988         for node in $(mdts_nodes); do
16989                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16990                         error "$node: GC-thread not done"
16991         done
16992
16993         do_nodes $mdts $LCTL set_param fail_loc=0
16994
16995         for (( i = 1; i <= MDSCOUNT; i++ )); do
16996                 # check cl_user1 is purged
16997                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16998                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16999         done
17000         return 0
17001 }
17002 run_test 160s "changelog garbage collect on idle records * time"
17003
17004 test_161a() {
17005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17006
17007         test_mkdir -c1 $DIR/$tdir
17008         cp /etc/hosts $DIR/$tdir/$tfile
17009         test_mkdir -c1 $DIR/$tdir/foo1
17010         test_mkdir -c1 $DIR/$tdir/foo2
17011         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17012         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17013         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17014         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17015         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17016         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17017                 $LFS fid2path $DIR $FID
17018                 error "bad link ea"
17019         fi
17020         # middle
17021         rm $DIR/$tdir/foo2/zachary
17022         # last
17023         rm $DIR/$tdir/foo2/thor
17024         # first
17025         rm $DIR/$tdir/$tfile
17026         # rename
17027         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17028         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17029                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17030         rm $DIR/$tdir/foo2/maggie
17031
17032         # overflow the EA
17033         local longname=$tfile.avg_len_is_thirty_two_
17034         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17035                 error_noexit 'failed to unlink many hardlinks'" EXIT
17036         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17037                 error "failed to hardlink many files"
17038         links=$($LFS fid2path $DIR $FID | wc -l)
17039         echo -n "${links}/1000 links in link EA"
17040         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17041 }
17042 run_test 161a "link ea sanity"
17043
17044 test_161b() {
17045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17046         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17047
17048         local MDTIDX=1
17049         local remote_dir=$DIR/$tdir/remote_dir
17050
17051         mkdir -p $DIR/$tdir
17052         $LFS mkdir -i $MDTIDX $remote_dir ||
17053                 error "create remote directory failed"
17054
17055         cp /etc/hosts $remote_dir/$tfile
17056         mkdir -p $remote_dir/foo1
17057         mkdir -p $remote_dir/foo2
17058         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17059         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17060         ln $remote_dir/$tfile $remote_dir/foo1/luna
17061         ln $remote_dir/$tfile $remote_dir/foo2/thor
17062
17063         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17064                      tr -d ']')
17065         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17066                 $LFS fid2path $DIR $FID
17067                 error "bad link ea"
17068         fi
17069         # middle
17070         rm $remote_dir/foo2/zachary
17071         # last
17072         rm $remote_dir/foo2/thor
17073         # first
17074         rm $remote_dir/$tfile
17075         # rename
17076         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17077         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17078         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17079                 $LFS fid2path $DIR $FID
17080                 error "bad link rename"
17081         fi
17082         rm $remote_dir/foo2/maggie
17083
17084         # overflow the EA
17085         local longname=filename_avg_len_is_thirty_two_
17086         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17087                 error "failed to hardlink many files"
17088         links=$($LFS fid2path $DIR $FID | wc -l)
17089         echo -n "${links}/1000 links in link EA"
17090         [[ ${links} -gt 60 ]] ||
17091                 error "expected at least 60 links in link EA"
17092         unlinkmany $remote_dir/foo2/$longname 1000 ||
17093         error "failed to unlink many hardlinks"
17094 }
17095 run_test 161b "link ea sanity under remote directory"
17096
17097 test_161c() {
17098         remote_mds_nodsh && skip "remote MDS with nodsh"
17099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17100         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17101                 skip "Need MDS version at least 2.1.5"
17102
17103         # define CLF_RENAME_LAST 0x0001
17104         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17105         changelog_register || error "changelog_register failed"
17106
17107         rm -rf $DIR/$tdir
17108         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17109         touch $DIR/$tdir/foo_161c
17110         touch $DIR/$tdir/bar_161c
17111         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17112         changelog_dump | grep RENME | tail -n 5
17113         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17114         changelog_clear 0 || error "changelog_clear failed"
17115         if [ x$flags != "x0x1" ]; then
17116                 error "flag $flags is not 0x1"
17117         fi
17118
17119         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17120         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17121         touch $DIR/$tdir/foo_161c
17122         touch $DIR/$tdir/bar_161c
17123         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17124         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17125         changelog_dump | grep RENME | tail -n 5
17126         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17127         changelog_clear 0 || error "changelog_clear failed"
17128         if [ x$flags != "x0x0" ]; then
17129                 error "flag $flags is not 0x0"
17130         fi
17131         echo "rename overwrite a target having nlink > 1," \
17132                 "changelog record has flags of $flags"
17133
17134         # rename doesn't overwrite a target (changelog flag 0x0)
17135         touch $DIR/$tdir/foo_161c
17136         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17137         changelog_dump | grep RENME | tail -n 5
17138         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17139         changelog_clear 0 || error "changelog_clear failed"
17140         if [ x$flags != "x0x0" ]; then
17141                 error "flag $flags is not 0x0"
17142         fi
17143         echo "rename doesn't overwrite a target," \
17144                 "changelog record has flags of $flags"
17145
17146         # define CLF_UNLINK_LAST 0x0001
17147         # unlink a file having nlink = 1 (changelog flag 0x1)
17148         rm -f $DIR/$tdir/foo2_161c
17149         changelog_dump | grep UNLNK | tail -n 5
17150         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17151         changelog_clear 0 || error "changelog_clear failed"
17152         if [ x$flags != "x0x1" ]; then
17153                 error "flag $flags is not 0x1"
17154         fi
17155         echo "unlink a file having nlink = 1," \
17156                 "changelog record has flags of $flags"
17157
17158         # unlink a file having nlink > 1 (changelog flag 0x0)
17159         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17160         rm -f $DIR/$tdir/foobar_161c
17161         changelog_dump | grep UNLNK | tail -n 5
17162         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17163         changelog_clear 0 || error "changelog_clear failed"
17164         if [ x$flags != "x0x0" ]; then
17165                 error "flag $flags is not 0x0"
17166         fi
17167         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17168 }
17169 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17170
17171 test_161d() {
17172         remote_mds_nodsh && skip "remote MDS with nodsh"
17173         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17174
17175         local pid
17176         local fid
17177
17178         changelog_register || error "changelog_register failed"
17179
17180         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17181         # interfer with $MOUNT/.lustre/fid/ access
17182         mkdir $DIR/$tdir
17183         [[ $? -eq 0 ]] || error "mkdir failed"
17184
17185         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17186         $LCTL set_param fail_loc=0x8000140c
17187         # 5s pause
17188         $LCTL set_param fail_val=5
17189
17190         # create file
17191         echo foofoo > $DIR/$tdir/$tfile &
17192         pid=$!
17193
17194         # wait for create to be delayed
17195         sleep 2
17196
17197         ps -p $pid
17198         [[ $? -eq 0 ]] || error "create should be blocked"
17199
17200         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17201         stack_trap "rm -f $tempfile"
17202         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17203         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17204         # some delay may occur during ChangeLog publishing and file read just
17205         # above, that could allow file write to happen finally
17206         [[ -s $tempfile ]] && echo "file should be empty"
17207
17208         $LCTL set_param fail_loc=0
17209
17210         wait $pid
17211         [[ $? -eq 0 ]] || error "create failed"
17212 }
17213 run_test 161d "create with concurrent .lustre/fid access"
17214
17215 check_path() {
17216         local expected="$1"
17217         shift
17218         local fid="$2"
17219
17220         local path
17221         path=$($LFS fid2path "$@")
17222         local rc=$?
17223
17224         if [ $rc -ne 0 ]; then
17225                 error "path looked up of '$expected' failed: rc=$rc"
17226         elif [ "$path" != "$expected" ]; then
17227                 error "path looked up '$path' instead of '$expected'"
17228         else
17229                 echo "FID '$fid' resolves to path '$path' as expected"
17230         fi
17231 }
17232
17233 test_162a() { # was test_162
17234         test_mkdir -p -c1 $DIR/$tdir/d2
17235         touch $DIR/$tdir/d2/$tfile
17236         touch $DIR/$tdir/d2/x1
17237         touch $DIR/$tdir/d2/x2
17238         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17239         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17240         # regular file
17241         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17242         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17243
17244         # softlink
17245         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17246         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17247         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17248
17249         # softlink to wrong file
17250         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17251         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17252         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17253
17254         # hardlink
17255         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17256         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17257         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17258         # fid2path dir/fsname should both work
17259         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17260         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17261
17262         # hardlink count: check that there are 2 links
17263         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17264         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17265
17266         # hardlink indexing: remove the first link
17267         rm $DIR/$tdir/d2/p/q/r/hlink
17268         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17269 }
17270 run_test 162a "path lookup sanity"
17271
17272 test_162b() {
17273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17274         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17275
17276         mkdir $DIR/$tdir
17277         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17278                                 error "create striped dir failed"
17279
17280         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17281                                         tail -n 1 | awk '{print $2}')
17282         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17283
17284         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17285         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17286
17287         # regular file
17288         for ((i=0;i<5;i++)); do
17289                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17290                         error "get fid for f$i failed"
17291                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17292
17293                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17294                         error "get fid for d$i failed"
17295                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17296         done
17297
17298         return 0
17299 }
17300 run_test 162b "striped directory path lookup sanity"
17301
17302 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17303 test_162c() {
17304         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17305                 skip "Need MDS version at least 2.7.51"
17306
17307         local lpath=$tdir.local
17308         local rpath=$tdir.remote
17309
17310         test_mkdir $DIR/$lpath
17311         test_mkdir $DIR/$rpath
17312
17313         for ((i = 0; i <= 101; i++)); do
17314                 lpath="$lpath/$i"
17315                 mkdir $DIR/$lpath
17316                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17317                         error "get fid for local directory $DIR/$lpath failed"
17318                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17319
17320                 rpath="$rpath/$i"
17321                 test_mkdir $DIR/$rpath
17322                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17323                         error "get fid for remote directory $DIR/$rpath failed"
17324                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17325         done
17326
17327         return 0
17328 }
17329 run_test 162c "fid2path works with paths 100 or more directories deep"
17330
17331 oalr_event_count() {
17332         local event="${1}"
17333         local trace="${2}"
17334
17335         awk -v name="${FSNAME}-OST0000" \
17336             -v event="${event}" \
17337             '$1 == "TRACE" && $2 == event && $3 == name' \
17338             "${trace}" |
17339         wc -l
17340 }
17341
17342 oalr_expect_event_count() {
17343         local event="${1}"
17344         local trace="${2}"
17345         local expect="${3}"
17346         local count
17347
17348         count=$(oalr_event_count "${event}" "${trace}")
17349         if ((count == expect)); then
17350                 return 0
17351         fi
17352
17353         error_noexit "${event} event count was '${count}', expected ${expect}"
17354         cat "${trace}" >&2
17355         exit 1
17356 }
17357
17358 cleanup_165() {
17359         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17360         stop ost1
17361         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17362 }
17363
17364 setup_165() {
17365         sync # Flush previous IOs so we can count log entries.
17366         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17367         stack_trap cleanup_165 EXIT
17368 }
17369
17370 test_165a() {
17371         local trace="/tmp/${tfile}.trace"
17372         local rc
17373         local count
17374
17375         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17376                 skip "OFD access log unsupported"
17377
17378         setup_165
17379         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17380         sleep 5
17381
17382         do_facet ost1 ofd_access_log_reader --list
17383         stop ost1
17384
17385         do_facet ost1 killall -TERM ofd_access_log_reader
17386         wait
17387         rc=$?
17388
17389         if ((rc != 0)); then
17390                 error "ofd_access_log_reader exited with rc = '${rc}'"
17391         fi
17392
17393         # Parse trace file for discovery events:
17394         oalr_expect_event_count alr_log_add "${trace}" 1
17395         oalr_expect_event_count alr_log_eof "${trace}" 1
17396         oalr_expect_event_count alr_log_free "${trace}" 1
17397 }
17398 run_test 165a "ofd access log discovery"
17399
17400 test_165b() {
17401         local trace="/tmp/${tfile}.trace"
17402         local file="${DIR}/${tfile}"
17403         local pfid1
17404         local pfid2
17405         local -a entry
17406         local rc
17407         local count
17408         local size
17409         local flags
17410
17411         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17412                 skip "OFD access log unsupported"
17413
17414         setup_165
17415         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17416         sleep 5
17417
17418         do_facet ost1 ofd_access_log_reader --list
17419
17420         lfs setstripe -c 1 -i 0 "${file}"
17421         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17422                 error "cannot create '${file}'"
17423
17424         sleep 5
17425         do_facet ost1 killall -TERM ofd_access_log_reader
17426         wait
17427         rc=$?
17428
17429         if ((rc != 0)); then
17430                 error "ofd_access_log_reader exited with rc = '${rc}'"
17431         fi
17432
17433         oalr_expect_event_count alr_log_entry "${trace}" 1
17434
17435         pfid1=$($LFS path2fid "${file}")
17436
17437         # 1     2             3   4    5     6   7    8    9     10
17438         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17439         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17440
17441         echo "entry = '${entry[*]}'" >&2
17442
17443         pfid2=${entry[4]}
17444         if [[ "${pfid1}" != "${pfid2}" ]]; then
17445                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17446         fi
17447
17448         size=${entry[8]}
17449         if ((size != 1048576)); then
17450                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17451         fi
17452
17453         flags=${entry[10]}
17454         if [[ "${flags}" != "w" ]]; then
17455                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17456         fi
17457
17458         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17459         sleep 5
17460
17461         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17462                 error "cannot read '${file}'"
17463         sleep 5
17464
17465         do_facet ost1 killall -TERM ofd_access_log_reader
17466         wait
17467         rc=$?
17468
17469         if ((rc != 0)); then
17470                 error "ofd_access_log_reader exited with rc = '${rc}'"
17471         fi
17472
17473         oalr_expect_event_count alr_log_entry "${trace}" 1
17474
17475         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17476         echo "entry = '${entry[*]}'" >&2
17477
17478         pfid2=${entry[4]}
17479         if [[ "${pfid1}" != "${pfid2}" ]]; then
17480                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17481         fi
17482
17483         size=${entry[8]}
17484         if ((size != 524288)); then
17485                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17486         fi
17487
17488         flags=${entry[10]}
17489         if [[ "${flags}" != "r" ]]; then
17490                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17491         fi
17492 }
17493 run_test 165b "ofd access log entries are produced and consumed"
17494
17495 test_165c() {
17496         local trace="/tmp/${tfile}.trace"
17497         local file="${DIR}/${tdir}/${tfile}"
17498
17499         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17500                 skip "OFD access log unsupported"
17501
17502         test_mkdir "${DIR}/${tdir}"
17503
17504         setup_165
17505         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17506         sleep 5
17507
17508         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17509
17510         # 4096 / 64 = 64. Create twice as many entries.
17511         for ((i = 0; i < 128; i++)); do
17512                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17513                         error "cannot create file"
17514         done
17515
17516         sync
17517
17518         do_facet ost1 killall -TERM ofd_access_log_reader
17519         wait
17520         rc=$?
17521         if ((rc != 0)); then
17522                 error "ofd_access_log_reader exited with rc = '${rc}'"
17523         fi
17524
17525         unlinkmany  "${file}-%d" 128
17526 }
17527 run_test 165c "full ofd access logs do not block IOs"
17528
17529 oal_get_read_count() {
17530         local stats="$1"
17531
17532         # STATS lustre-OST0001 alr_read_count 1
17533
17534         do_facet ost1 cat "${stats}" |
17535         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17536              END { print count; }'
17537 }
17538
17539 oal_expect_read_count() {
17540         local stats="$1"
17541         local count
17542         local expect="$2"
17543
17544         # Ask ofd_access_log_reader to write stats.
17545         do_facet ost1 killall -USR1 ofd_access_log_reader
17546
17547         # Allow some time for things to happen.
17548         sleep 1
17549
17550         count=$(oal_get_read_count "${stats}")
17551         if ((count == expect)); then
17552                 return 0
17553         fi
17554
17555         error_noexit "bad read count, got ${count}, expected ${expect}"
17556         do_facet ost1 cat "${stats}" >&2
17557         exit 1
17558 }
17559
17560 test_165d() {
17561         local stats="/tmp/${tfile}.stats"
17562         local file="${DIR}/${tdir}/${tfile}"
17563         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17564
17565         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17566                 skip "OFD access log unsupported"
17567
17568         test_mkdir "${DIR}/${tdir}"
17569
17570         setup_165
17571         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17572         sleep 5
17573
17574         lfs setstripe -c 1 -i 0 "${file}"
17575
17576         do_facet ost1 lctl set_param "${param}=rw"
17577         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17578                 error "cannot create '${file}'"
17579         oal_expect_read_count "${stats}" 1
17580
17581         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17582                 error "cannot read '${file}'"
17583         oal_expect_read_count "${stats}" 2
17584
17585         do_facet ost1 lctl set_param "${param}=r"
17586         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17587                 error "cannot create '${file}'"
17588         oal_expect_read_count "${stats}" 2
17589
17590         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17591                 error "cannot read '${file}'"
17592         oal_expect_read_count "${stats}" 3
17593
17594         do_facet ost1 lctl set_param "${param}=w"
17595         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17596                 error "cannot create '${file}'"
17597         oal_expect_read_count "${stats}" 4
17598
17599         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17600                 error "cannot read '${file}'"
17601         oal_expect_read_count "${stats}" 4
17602
17603         do_facet ost1 lctl set_param "${param}=0"
17604         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17605                 error "cannot create '${file}'"
17606         oal_expect_read_count "${stats}" 4
17607
17608         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17609                 error "cannot read '${file}'"
17610         oal_expect_read_count "${stats}" 4
17611
17612         do_facet ost1 killall -TERM ofd_access_log_reader
17613         wait
17614         rc=$?
17615         if ((rc != 0)); then
17616                 error "ofd_access_log_reader exited with rc = '${rc}'"
17617         fi
17618 }
17619 run_test 165d "ofd_access_log mask works"
17620
17621 test_165e() {
17622         local stats="/tmp/${tfile}.stats"
17623         local file0="${DIR}/${tdir}-0/${tfile}"
17624         local file1="${DIR}/${tdir}-1/${tfile}"
17625
17626         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17627                 skip "OFD access log unsupported"
17628
17629         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17630
17631         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17632         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17633
17634         lfs setstripe -c 1 -i 0 "${file0}"
17635         lfs setstripe -c 1 -i 0 "${file1}"
17636
17637         setup_165
17638         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17639         sleep 5
17640
17641         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17642                 error "cannot create '${file0}'"
17643         sync
17644         oal_expect_read_count "${stats}" 0
17645
17646         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17647                 error "cannot create '${file1}'"
17648         sync
17649         oal_expect_read_count "${stats}" 1
17650
17651         do_facet ost1 killall -TERM ofd_access_log_reader
17652         wait
17653         rc=$?
17654         if ((rc != 0)); then
17655                 error "ofd_access_log_reader exited with rc = '${rc}'"
17656         fi
17657 }
17658 run_test 165e "ofd_access_log MDT index filter works"
17659
17660 test_165f() {
17661         local trace="/tmp/${tfile}.trace"
17662         local rc
17663         local count
17664
17665         setup_165
17666         do_facet ost1 timeout 60 ofd_access_log_reader \
17667                 --exit-on-close --debug=- --trace=- > "${trace}" &
17668         sleep 5
17669         stop ost1
17670
17671         wait
17672         rc=$?
17673
17674         if ((rc != 0)); then
17675                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17676                 cat "${trace}"
17677                 exit 1
17678         fi
17679 }
17680 run_test 165f "ofd_access_log_reader --exit-on-close works"
17681
17682 test_169() {
17683         # do directio so as not to populate the page cache
17684         log "creating a 10 Mb file"
17685         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17686                 error "multiop failed while creating a file"
17687         log "starting reads"
17688         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17689         log "truncating the file"
17690         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17691                 error "multiop failed while truncating the file"
17692         log "killing dd"
17693         kill %+ || true # reads might have finished
17694         echo "wait until dd is finished"
17695         wait
17696         log "removing the temporary file"
17697         rm -rf $DIR/$tfile || error "tmp file removal failed"
17698 }
17699 run_test 169 "parallel read and truncate should not deadlock"
17700
17701 test_170() {
17702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17703
17704         $LCTL clear     # bug 18514
17705         $LCTL debug_daemon start $TMP/${tfile}_log_good
17706         touch $DIR/$tfile
17707         $LCTL debug_daemon stop
17708         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17709                 error "sed failed to read log_good"
17710
17711         $LCTL debug_daemon start $TMP/${tfile}_log_good
17712         rm -rf $DIR/$tfile
17713         $LCTL debug_daemon stop
17714
17715         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17716                error "lctl df log_bad failed"
17717
17718         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17719         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17720
17721         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17722         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17723
17724         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17725                 error "bad_line good_line1 good_line2 are empty"
17726
17727         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17728         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17729         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17730
17731         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17732         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17733         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17734
17735         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17736                 error "bad_line_new good_line_new are empty"
17737
17738         local expected_good=$((good_line1 + good_line2*2))
17739
17740         rm -f $TMP/${tfile}*
17741         # LU-231, short malformed line may not be counted into bad lines
17742         if [ $bad_line -ne $bad_line_new ] &&
17743                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17744                 error "expected $bad_line bad lines, but got $bad_line_new"
17745                 return 1
17746         fi
17747
17748         if [ $expected_good -ne $good_line_new ]; then
17749                 error "expected $expected_good good lines, but got $good_line_new"
17750                 return 2
17751         fi
17752         true
17753 }
17754 run_test 170 "test lctl df to handle corrupted log ====================="
17755
17756 test_171() { # bug20592
17757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17758
17759         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17760         $LCTL set_param fail_loc=0x50e
17761         $LCTL set_param fail_val=3000
17762         multiop_bg_pause $DIR/$tfile O_s || true
17763         local MULTIPID=$!
17764         kill -USR1 $MULTIPID
17765         # cause log dump
17766         sleep 3
17767         wait $MULTIPID
17768         if dmesg | grep "recursive fault"; then
17769                 error "caught a recursive fault"
17770         fi
17771         $LCTL set_param fail_loc=0
17772         true
17773 }
17774 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17775
17776 # it would be good to share it with obdfilter-survey/iokit-libecho code
17777 setup_obdecho_osc () {
17778         local rc=0
17779         local ost_nid=$1
17780         local obdfilter_name=$2
17781         echo "Creating new osc for $obdfilter_name on $ost_nid"
17782         # make sure we can find loopback nid
17783         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17784
17785         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17786                            ${obdfilter_name}_osc_UUID || rc=2; }
17787         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17788                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17789         return $rc
17790 }
17791
17792 cleanup_obdecho_osc () {
17793         local obdfilter_name=$1
17794         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17795         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17796         return 0
17797 }
17798
17799 obdecho_test() {
17800         local OBD=$1
17801         local node=$2
17802         local pages=${3:-64}
17803         local rc=0
17804         local id
17805
17806         local count=10
17807         local obd_size=$(get_obd_size $node $OBD)
17808         local page_size=$(get_page_size $node)
17809         if [[ -n "$obd_size" ]]; then
17810                 local new_count=$((obd_size / (pages * page_size / 1024)))
17811                 [[ $new_count -ge $count ]] || count=$new_count
17812         fi
17813
17814         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17815         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17816                            rc=2; }
17817         if [ $rc -eq 0 ]; then
17818             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17819             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17820         fi
17821         echo "New object id is $id"
17822         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17823                            rc=4; }
17824         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17825                            "test_brw $count w v $pages $id" || rc=4; }
17826         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17827                            rc=4; }
17828         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17829                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17830         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17831                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17832         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17833         return $rc
17834 }
17835
17836 test_180a() {
17837         skip "obdecho on osc is no longer supported"
17838 }
17839 run_test 180a "test obdecho on osc"
17840
17841 test_180b() {
17842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17843         remote_ost_nodsh && skip "remote OST with nodsh"
17844
17845         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17846                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17847                 error "failed to load module obdecho"
17848
17849         local target=$(do_facet ost1 $LCTL dl |
17850                        awk '/obdfilter/ { print $4; exit; }')
17851
17852         if [ -n "$target" ]; then
17853                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17854         else
17855                 do_facet ost1 $LCTL dl
17856                 error "there is no obdfilter target on ost1"
17857         fi
17858 }
17859 run_test 180b "test obdecho directly on obdfilter"
17860
17861 test_180c() { # LU-2598
17862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17863         remote_ost_nodsh && skip "remote OST with nodsh"
17864         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17865                 skip "Need MDS version at least 2.4.0"
17866
17867         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17868                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17869                 error "failed to load module obdecho"
17870
17871         local target=$(do_facet ost1 $LCTL dl |
17872                        awk '/obdfilter/ { print $4; exit; }')
17873
17874         if [ -n "$target" ]; then
17875                 local pages=16384 # 64MB bulk I/O RPC size
17876
17877                 obdecho_test "$target" ost1 "$pages" ||
17878                         error "obdecho_test with pages=$pages failed with $?"
17879         else
17880                 do_facet ost1 $LCTL dl
17881                 error "there is no obdfilter target on ost1"
17882         fi
17883 }
17884 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17885
17886 test_181() { # bug 22177
17887         test_mkdir $DIR/$tdir
17888         # create enough files to index the directory
17889         createmany -o $DIR/$tdir/foobar 4000
17890         # print attributes for debug purpose
17891         lsattr -d .
17892         # open dir
17893         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17894         MULTIPID=$!
17895         # remove the files & current working dir
17896         unlinkmany $DIR/$tdir/foobar 4000
17897         rmdir $DIR/$tdir
17898         kill -USR1 $MULTIPID
17899         wait $MULTIPID
17900         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17901         return 0
17902 }
17903 run_test 181 "Test open-unlinked dir ========================"
17904
17905 test_182a() {
17906         local fcount=1000
17907         local tcount=10
17908
17909         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17910
17911         $LCTL set_param mdc.*.rpc_stats=clear
17912
17913         for (( i = 0; i < $tcount; i++ )) ; do
17914                 mkdir $DIR/$tdir/$i
17915         done
17916
17917         for (( i = 0; i < $tcount; i++ )) ; do
17918                 createmany -o $DIR/$tdir/$i/f- $fcount &
17919         done
17920         wait
17921
17922         for (( i = 0; i < $tcount; i++ )) ; do
17923                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17924         done
17925         wait
17926
17927         $LCTL get_param mdc.*.rpc_stats
17928
17929         rm -rf $DIR/$tdir
17930 }
17931 run_test 182a "Test parallel modify metadata operations from mdc"
17932
17933 test_182b() {
17934         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17935         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
17936         local dcount=1000
17937         local tcount=10
17938         local stime
17939         local etime
17940         local delta
17941
17942         do_facet mds1 $LCTL list_param \
17943                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
17944                 skip "MDS lacks parallel RPC handling"
17945
17946         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17947
17948         rpc_count=$(do_facet mds1 $LCTL get_param -n \
17949                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
17950
17951         stime=$(date +%s)
17952         createmany -i 0 -d $DIR/$tdir/t- $tcount
17953
17954         for (( i = 0; i < $tcount; i++ )) ; do
17955                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17956         done
17957         wait
17958         etime=$(date +%s)
17959         delta=$((etime - stime))
17960         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
17961
17962         stime=$(date +%s)
17963         for (( i = 0; i < $tcount; i++ )) ; do
17964                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
17965         done
17966         wait
17967         etime=$(date +%s)
17968         delta=$((etime - stime))
17969         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
17970
17971         rm -rf $DIR/$tdir
17972
17973         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17974
17975         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
17976
17977         stime=$(date +%s)
17978         createmany -i 0 -d $DIR/$tdir/t- $tcount
17979
17980         for (( i = 0; i < $tcount; i++ )) ; do
17981                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17982         done
17983         wait
17984         etime=$(date +%s)
17985         delta=$((etime - stime))
17986         echo "Time for file creation $delta sec for 1 RPC sent at a time"
17987
17988         stime=$(date +%s)
17989         for (( i = 0; i < $tcount; i++ )) ; do
17990                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
17991         done
17992         wait
17993         etime=$(date +%s)
17994         delta=$((etime - stime))
17995         echo "Time for file removal $delta sec for 1 RPC sent at a time"
17996
17997         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
17998 }
17999 run_test 182b "Test parallel modify metadata operations from osp"
18000
18001 test_183() { # LU-2275
18002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18003         remote_mds_nodsh && skip "remote MDS with nodsh"
18004         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18005                 skip "Need MDS version at least 2.3.56"
18006
18007         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18008         echo aaa > $DIR/$tdir/$tfile
18009
18010 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18011         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18012
18013         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18014         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18015
18016         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18017
18018         # Flush negative dentry cache
18019         touch $DIR/$tdir/$tfile
18020
18021         # We are not checking for any leaked references here, they'll
18022         # become evident next time we do cleanup with module unload.
18023         rm -rf $DIR/$tdir
18024 }
18025 run_test 183 "No crash or request leak in case of strange dispositions ========"
18026
18027 # test suite 184 is for LU-2016, LU-2017
18028 test_184a() {
18029         check_swap_layouts_support
18030
18031         dir0=$DIR/$tdir/$testnum
18032         test_mkdir -p -c1 $dir0
18033         ref1=/etc/passwd
18034         ref2=/etc/group
18035         file1=$dir0/f1
18036         file2=$dir0/f2
18037         $LFS setstripe -c1 $file1
18038         cp $ref1 $file1
18039         $LFS setstripe -c2 $file2
18040         cp $ref2 $file2
18041         gen1=$($LFS getstripe -g $file1)
18042         gen2=$($LFS getstripe -g $file2)
18043
18044         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18045         gen=$($LFS getstripe -g $file1)
18046         [[ $gen1 != $gen ]] ||
18047                 error "Layout generation on $file1 does not change"
18048         gen=$($LFS getstripe -g $file2)
18049         [[ $gen2 != $gen ]] ||
18050                 error "Layout generation on $file2 does not change"
18051
18052         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18053         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18054
18055         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18056 }
18057 run_test 184a "Basic layout swap"
18058
18059 test_184b() {
18060         check_swap_layouts_support
18061
18062         dir0=$DIR/$tdir/$testnum
18063         mkdir -p $dir0 || error "creating dir $dir0"
18064         file1=$dir0/f1
18065         file2=$dir0/f2
18066         file3=$dir0/f3
18067         dir1=$dir0/d1
18068         dir2=$dir0/d2
18069         mkdir $dir1 $dir2
18070         $LFS setstripe -c1 $file1
18071         $LFS setstripe -c2 $file2
18072         $LFS setstripe -c1 $file3
18073         chown $RUNAS_ID $file3
18074         gen1=$($LFS getstripe -g $file1)
18075         gen2=$($LFS getstripe -g $file2)
18076
18077         $LFS swap_layouts $dir1 $dir2 &&
18078                 error "swap of directories layouts should fail"
18079         $LFS swap_layouts $dir1 $file1 &&
18080                 error "swap of directory and file layouts should fail"
18081         $RUNAS $LFS swap_layouts $file1 $file2 &&
18082                 error "swap of file we cannot write should fail"
18083         $LFS swap_layouts $file1 $file3 &&
18084                 error "swap of file with different owner should fail"
18085         /bin/true # to clear error code
18086 }
18087 run_test 184b "Forbidden layout swap (will generate errors)"
18088
18089 test_184c() {
18090         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18091         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18092         check_swap_layouts_support
18093         check_swap_layout_no_dom $DIR
18094
18095         local dir0=$DIR/$tdir/$testnum
18096         mkdir -p $dir0 || error "creating dir $dir0"
18097
18098         local ref1=$dir0/ref1
18099         local ref2=$dir0/ref2
18100         local file1=$dir0/file1
18101         local file2=$dir0/file2
18102         # create a file large enough for the concurrent test
18103         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18104         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18105         echo "ref file size: ref1($(stat -c %s $ref1))," \
18106              "ref2($(stat -c %s $ref2))"
18107
18108         cp $ref2 $file2
18109         dd if=$ref1 of=$file1 bs=16k &
18110         local DD_PID=$!
18111
18112         # Make sure dd starts to copy file, but wait at most 5 seconds
18113         local loops=0
18114         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18115
18116         $LFS swap_layouts $file1 $file2
18117         local rc=$?
18118         wait $DD_PID
18119         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18120         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18121
18122         # how many bytes copied before swapping layout
18123         local copied=$(stat -c %s $file2)
18124         local remaining=$(stat -c %s $ref1)
18125         remaining=$((remaining - copied))
18126         echo "Copied $copied bytes before swapping layout..."
18127
18128         cmp -n $copied $file1 $ref2 | grep differ &&
18129                 error "Content mismatch [0, $copied) of ref2 and file1"
18130         cmp -n $copied $file2 $ref1 ||
18131                 error "Content mismatch [0, $copied) of ref1 and file2"
18132         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18133                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18134
18135         # clean up
18136         rm -f $ref1 $ref2 $file1 $file2
18137 }
18138 run_test 184c "Concurrent write and layout swap"
18139
18140 test_184d() {
18141         check_swap_layouts_support
18142         check_swap_layout_no_dom $DIR
18143         [ -z "$(which getfattr 2>/dev/null)" ] &&
18144                 skip_env "no getfattr command"
18145
18146         local file1=$DIR/$tdir/$tfile-1
18147         local file2=$DIR/$tdir/$tfile-2
18148         local file3=$DIR/$tdir/$tfile-3
18149         local lovea1
18150         local lovea2
18151
18152         mkdir -p $DIR/$tdir
18153         touch $file1 || error "create $file1 failed"
18154         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18155                 error "create $file2 failed"
18156         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18157                 error "create $file3 failed"
18158         lovea1=$(get_layout_param $file1)
18159
18160         $LFS swap_layouts $file2 $file3 ||
18161                 error "swap $file2 $file3 layouts failed"
18162         $LFS swap_layouts $file1 $file2 ||
18163                 error "swap $file1 $file2 layouts failed"
18164
18165         lovea2=$(get_layout_param $file2)
18166         echo "$lovea1"
18167         echo "$lovea2"
18168         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18169
18170         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18171         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18172 }
18173 run_test 184d "allow stripeless layouts swap"
18174
18175 test_184e() {
18176         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18177                 skip "Need MDS version at least 2.6.94"
18178         check_swap_layouts_support
18179         check_swap_layout_no_dom $DIR
18180         [ -z "$(which getfattr 2>/dev/null)" ] &&
18181                 skip_env "no getfattr command"
18182
18183         local file1=$DIR/$tdir/$tfile-1
18184         local file2=$DIR/$tdir/$tfile-2
18185         local file3=$DIR/$tdir/$tfile-3
18186         local lovea
18187
18188         mkdir -p $DIR/$tdir
18189         touch $file1 || error "create $file1 failed"
18190         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18191                 error "create $file2 failed"
18192         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18193                 error "create $file3 failed"
18194
18195         $LFS swap_layouts $file1 $file2 ||
18196                 error "swap $file1 $file2 layouts failed"
18197
18198         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18199         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18200
18201         echo 123 > $file1 || error "Should be able to write into $file1"
18202
18203         $LFS swap_layouts $file1 $file3 ||
18204                 error "swap $file1 $file3 layouts failed"
18205
18206         echo 123 > $file1 || error "Should be able to write into $file1"
18207
18208         rm -rf $file1 $file2 $file3
18209 }
18210 run_test 184e "Recreate layout after stripeless layout swaps"
18211
18212 test_184f() {
18213         # Create a file with name longer than sizeof(struct stat) ==
18214         # 144 to see if we can get chars from the file name to appear
18215         # in the returned striping. Note that 'f' == 0x66.
18216         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18217
18218         mkdir -p $DIR/$tdir
18219         mcreate $DIR/$tdir/$file
18220         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18221                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18222         fi
18223 }
18224 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18225
18226 test_185() { # LU-2441
18227         # LU-3553 - no volatile file support in old servers
18228         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18229                 skip "Need MDS version at least 2.3.60"
18230
18231         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18232         touch $DIR/$tdir/spoo
18233         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18234         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18235                 error "cannot create/write a volatile file"
18236         [ "$FILESET" == "" ] &&
18237         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18238                 error "FID is still valid after close"
18239
18240         multiop_bg_pause $DIR/$tdir vVw4096_c
18241         local multi_pid=$!
18242
18243         local OLD_IFS=$IFS
18244         IFS=":"
18245         local fidv=($fid)
18246         IFS=$OLD_IFS
18247         # assume that the next FID for this client is sequential, since stdout
18248         # is unfortunately eaten by multiop_bg_pause
18249         local n=$((${fidv[1]} + 1))
18250         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18251         if [ "$FILESET" == "" ]; then
18252                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18253                         error "FID is missing before close"
18254         fi
18255         kill -USR1 $multi_pid
18256         # 1 second delay, so if mtime change we will see it
18257         sleep 1
18258         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18259         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18260 }
18261 run_test 185 "Volatile file support"
18262
18263 function create_check_volatile() {
18264         local idx=$1
18265         local tgt
18266
18267         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18268         local PID=$!
18269         sleep 1
18270         local FID=$(cat /tmp/${tfile}.fid)
18271         [ "$FID" == "" ] && error "can't get FID for volatile"
18272         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18273         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18274         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18275         kill -USR1 $PID
18276         wait
18277         sleep 1
18278         cancel_lru_locks mdc # flush opencache
18279         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18280         return 0
18281 }
18282
18283 test_185a(){
18284         # LU-12516 - volatile creation via .lustre
18285         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18286                 skip "Need MDS version at least 2.3.55"
18287
18288         create_check_volatile 0
18289         [ $MDSCOUNT -lt 2 ] && return 0
18290
18291         # DNE case
18292         create_check_volatile 1
18293
18294         return 0
18295 }
18296 run_test 185a "Volatile file creation in .lustre/fid/"
18297
18298 test_187a() {
18299         remote_mds_nodsh && skip "remote MDS with nodsh"
18300         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18301                 skip "Need MDS version at least 2.3.0"
18302
18303         local dir0=$DIR/$tdir/$testnum
18304         mkdir -p $dir0 || error "creating dir $dir0"
18305
18306         local file=$dir0/file1
18307         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18308         local dv1=$($LFS data_version $file)
18309         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18310         local dv2=$($LFS data_version $file)
18311         [[ $dv1 != $dv2 ]] ||
18312                 error "data version did not change on write $dv1 == $dv2"
18313
18314         # clean up
18315         rm -f $file1
18316 }
18317 run_test 187a "Test data version change"
18318
18319 test_187b() {
18320         remote_mds_nodsh && skip "remote MDS with nodsh"
18321         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18322                 skip "Need MDS version at least 2.3.0"
18323
18324         local dir0=$DIR/$tdir/$testnum
18325         mkdir -p $dir0 || error "creating dir $dir0"
18326
18327         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18328         [[ ${DV[0]} != ${DV[1]} ]] ||
18329                 error "data version did not change on write"\
18330                       " ${DV[0]} == ${DV[1]}"
18331
18332         # clean up
18333         rm -f $file1
18334 }
18335 run_test 187b "Test data version change on volatile file"
18336
18337 test_200() {
18338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18339         remote_mgs_nodsh && skip "remote MGS with nodsh"
18340         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18341
18342         local POOL=${POOL:-cea1}
18343         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18344         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18345         # Pool OST targets
18346         local first_ost=0
18347         local last_ost=$(($OSTCOUNT - 1))
18348         local ost_step=2
18349         local ost_list=$(seq $first_ost $ost_step $last_ost)
18350         local ost_range="$first_ost $last_ost $ost_step"
18351         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18352         local file_dir=$POOL_ROOT/file_tst
18353         local subdir=$test_path/subdir
18354         local rc=0
18355
18356         while : ; do
18357                 # former test_200a test_200b
18358                 pool_add $POOL                          || { rc=$? ; break; }
18359                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18360                 # former test_200c test_200d
18361                 mkdir -p $test_path
18362                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18363                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18364                 mkdir -p $subdir
18365                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18366                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18367                                                         || { rc=$? ; break; }
18368                 # former test_200e test_200f
18369                 local files=$((OSTCOUNT*3))
18370                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18371                                                         || { rc=$? ; break; }
18372                 pool_create_files $POOL $file_dir $files "$ost_list" \
18373                                                         || { rc=$? ; break; }
18374                 # former test_200g test_200h
18375                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18376                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18377
18378                 # former test_201a test_201b test_201c
18379                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18380
18381                 local f=$test_path/$tfile
18382                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18383                 pool_remove $POOL $f                    || { rc=$? ; break; }
18384                 break
18385         done
18386
18387         destroy_test_pools
18388
18389         return $rc
18390 }
18391 run_test 200 "OST pools"
18392
18393 # usage: default_attr <count | size | offset>
18394 default_attr() {
18395         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18396 }
18397
18398 # usage: check_default_stripe_attr
18399 check_default_stripe_attr() {
18400         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18401         case $1 in
18402         --stripe-count|-c)
18403                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18404         --stripe-size|-S)
18405                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18406         --stripe-index|-i)
18407                 EXPECTED=-1;;
18408         *)
18409                 error "unknown getstripe attr '$1'"
18410         esac
18411
18412         [ $ACTUAL == $EXPECTED ] ||
18413                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18414 }
18415
18416 test_204a() {
18417         test_mkdir $DIR/$tdir
18418         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18419
18420         check_default_stripe_attr --stripe-count
18421         check_default_stripe_attr --stripe-size
18422         check_default_stripe_attr --stripe-index
18423 }
18424 run_test 204a "Print default stripe attributes"
18425
18426 test_204b() {
18427         test_mkdir $DIR/$tdir
18428         $LFS setstripe --stripe-count 1 $DIR/$tdir
18429
18430         check_default_stripe_attr --stripe-size
18431         check_default_stripe_attr --stripe-index
18432 }
18433 run_test 204b "Print default stripe size and offset"
18434
18435 test_204c() {
18436         test_mkdir $DIR/$tdir
18437         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18438
18439         check_default_stripe_attr --stripe-count
18440         check_default_stripe_attr --stripe-index
18441 }
18442 run_test 204c "Print default stripe count and offset"
18443
18444 test_204d() {
18445         test_mkdir $DIR/$tdir
18446         $LFS setstripe --stripe-index 0 $DIR/$tdir
18447
18448         check_default_stripe_attr --stripe-count
18449         check_default_stripe_attr --stripe-size
18450 }
18451 run_test 204d "Print default stripe count and size"
18452
18453 test_204e() {
18454         test_mkdir $DIR/$tdir
18455         $LFS setstripe -d $DIR/$tdir
18456
18457         check_default_stripe_attr --stripe-count --raw
18458         check_default_stripe_attr --stripe-size --raw
18459         check_default_stripe_attr --stripe-index --raw
18460 }
18461 run_test 204e "Print raw stripe attributes"
18462
18463 test_204f() {
18464         test_mkdir $DIR/$tdir
18465         $LFS setstripe --stripe-count 1 $DIR/$tdir
18466
18467         check_default_stripe_attr --stripe-size --raw
18468         check_default_stripe_attr --stripe-index --raw
18469 }
18470 run_test 204f "Print raw stripe size and offset"
18471
18472 test_204g() {
18473         test_mkdir $DIR/$tdir
18474         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18475
18476         check_default_stripe_attr --stripe-count --raw
18477         check_default_stripe_attr --stripe-index --raw
18478 }
18479 run_test 204g "Print raw stripe count and offset"
18480
18481 test_204h() {
18482         test_mkdir $DIR/$tdir
18483         $LFS setstripe --stripe-index 0 $DIR/$tdir
18484
18485         check_default_stripe_attr --stripe-count --raw
18486         check_default_stripe_attr --stripe-size --raw
18487 }
18488 run_test 204h "Print raw stripe count and size"
18489
18490 # Figure out which job scheduler is being used, if any,
18491 # or use a fake one
18492 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18493         JOBENV=SLURM_JOB_ID
18494 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18495         JOBENV=LSB_JOBID
18496 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18497         JOBENV=PBS_JOBID
18498 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18499         JOBENV=LOADL_STEP_ID
18500 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18501         JOBENV=JOB_ID
18502 else
18503         $LCTL list_param jobid_name > /dev/null 2>&1
18504         if [ $? -eq 0 ]; then
18505                 JOBENV=nodelocal
18506         else
18507                 JOBENV=FAKE_JOBID
18508         fi
18509 fi
18510 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18511
18512 verify_jobstats() {
18513         local cmd=($1)
18514         shift
18515         local facets="$@"
18516
18517 # we don't really need to clear the stats for this test to work, since each
18518 # command has a unique jobid, but it makes debugging easier if needed.
18519 #       for facet in $facets; do
18520 #               local dev=$(convert_facet2label $facet)
18521 #               # clear old jobstats
18522 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18523 #       done
18524
18525         # use a new JobID for each test, or we might see an old one
18526         [ "$JOBENV" = "FAKE_JOBID" ] &&
18527                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18528
18529         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18530
18531         [ "$JOBENV" = "nodelocal" ] && {
18532                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18533                 $LCTL set_param jobid_name=$FAKE_JOBID
18534                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18535         }
18536
18537         log "Test: ${cmd[*]}"
18538         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18539
18540         if [ $JOBENV = "FAKE_JOBID" ]; then
18541                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18542         else
18543                 ${cmd[*]}
18544         fi
18545
18546         # all files are created on OST0000
18547         for facet in $facets; do
18548                 local stats="*.$(convert_facet2label $facet).job_stats"
18549
18550                 # strip out libtool wrappers for in-tree executables
18551                 if (( $(do_facet $facet lctl get_param $stats |
18552                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18553                         do_facet $facet lctl get_param $stats
18554                         error "No jobstats for $JOBVAL found on $facet::$stats"
18555                 fi
18556         done
18557 }
18558
18559 jobstats_set() {
18560         local new_jobenv=$1
18561
18562         set_persistent_param_and_check client "jobid_var" \
18563                 "$FSNAME.sys.jobid_var" $new_jobenv
18564 }
18565
18566 test_205a() { # Job stats
18567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18568         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18569                 skip "Need MDS version with at least 2.7.1"
18570         remote_mgs_nodsh && skip "remote MGS with nodsh"
18571         remote_mds_nodsh && skip "remote MDS with nodsh"
18572         remote_ost_nodsh && skip "remote OST with nodsh"
18573         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18574                 skip "Server doesn't support jobstats"
18575         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18576
18577         local old_jobenv=$($LCTL get_param -n jobid_var)
18578         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18579
18580         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18581                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18582         else
18583                 stack_trap "do_facet mgs $PERM_CMD \
18584                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18585         fi
18586         changelog_register
18587
18588         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18589                                 mdt.*.job_cleanup_interval | head -n 1)
18590         local new_interval=5
18591         do_facet $SINGLEMDS \
18592                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18593         stack_trap "do_facet $SINGLEMDS \
18594                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18595         local start=$SECONDS
18596
18597         local cmd
18598         # mkdir
18599         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18600         verify_jobstats "$cmd" "$SINGLEMDS"
18601         # rmdir
18602         cmd="rmdir $DIR/$tdir"
18603         verify_jobstats "$cmd" "$SINGLEMDS"
18604         # mkdir on secondary MDT
18605         if [ $MDSCOUNT -gt 1 ]; then
18606                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18607                 verify_jobstats "$cmd" "mds2"
18608         fi
18609         # mknod
18610         cmd="mknod $DIR/$tfile c 1 3"
18611         verify_jobstats "$cmd" "$SINGLEMDS"
18612         # unlink
18613         cmd="rm -f $DIR/$tfile"
18614         verify_jobstats "$cmd" "$SINGLEMDS"
18615         # create all files on OST0000 so verify_jobstats can find OST stats
18616         # open & close
18617         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18618         verify_jobstats "$cmd" "$SINGLEMDS"
18619         # setattr
18620         cmd="touch $DIR/$tfile"
18621         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18622         # write
18623         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18624         verify_jobstats "$cmd" "ost1"
18625         # read
18626         cancel_lru_locks osc
18627         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18628         verify_jobstats "$cmd" "ost1"
18629         # truncate
18630         cmd="$TRUNCATE $DIR/$tfile 0"
18631         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18632         # rename
18633         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18634         verify_jobstats "$cmd" "$SINGLEMDS"
18635         # jobstats expiry - sleep until old stats should be expired
18636         local left=$((new_interval + 5 - (SECONDS - start)))
18637         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18638                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18639                         "0" $left
18640         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18641         verify_jobstats "$cmd" "$SINGLEMDS"
18642         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18643             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18644
18645         # Ensure that jobid are present in changelog (if supported by MDS)
18646         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18647                 changelog_dump | tail -10
18648                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18649                 [ $jobids -eq 9 ] ||
18650                         error "Wrong changelog jobid count $jobids != 9"
18651
18652                 # LU-5862
18653                 JOBENV="disable"
18654                 jobstats_set $JOBENV
18655                 touch $DIR/$tfile
18656                 changelog_dump | grep $tfile
18657                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18658                 [ $jobids -eq 0 ] ||
18659                         error "Unexpected jobids when jobid_var=$JOBENV"
18660         fi
18661
18662         # test '%j' access to environment variable - if supported
18663         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18664                 JOBENV="JOBCOMPLEX"
18665                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18666
18667                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18668         fi
18669
18670         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18671                 JOBENV="JOBCOMPLEX"
18672                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18673
18674                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18675         fi
18676
18677         # test '%j' access to per-session jobid - if supported
18678         if lctl list_param jobid_this_session > /dev/null 2>&1
18679         then
18680                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18681                 lctl set_param jobid_this_session=$USER
18682
18683                 JOBENV="JOBCOMPLEX"
18684                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18685
18686                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18687         fi
18688 }
18689 run_test 205a "Verify job stats"
18690
18691 # LU-13117, LU-13597
18692 test_205b() {
18693         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18694                 skip "Need MDS version at least 2.13.54.91"
18695
18696         job_stats="mdt.*.job_stats"
18697         $LCTL set_param $job_stats=clear
18698         # Setting jobid_var to USER might not be supported
18699         $LCTL set_param jobid_var=USER || true
18700         $LCTL set_param jobid_name="%e.%u"
18701         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18702         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18703                 grep "job_id:.*foolish" &&
18704                         error "Unexpected jobid found"
18705         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18706                 grep "open:.*min.*max.*sum" ||
18707                         error "wrong job_stats format found"
18708 }
18709 run_test 205b "Verify job stats jobid and output format"
18710
18711 # LU-13733
18712 test_205c() {
18713         $LCTL set_param llite.*.stats=0
18714         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18715         $LCTL get_param llite.*.stats
18716         $LCTL get_param llite.*.stats | grep \
18717                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18718                         error "wrong client stats format found"
18719 }
18720 run_test 205c "Verify client stats format"
18721
18722 # LU-1480, LU-1773 and LU-1657
18723 test_206() {
18724         mkdir -p $DIR/$tdir
18725         $LFS setstripe -c -1 $DIR/$tdir
18726 #define OBD_FAIL_LOV_INIT 0x1403
18727         $LCTL set_param fail_loc=0xa0001403
18728         $LCTL set_param fail_val=1
18729         touch $DIR/$tdir/$tfile || true
18730 }
18731 run_test 206 "fail lov_init_raid0() doesn't lbug"
18732
18733 test_207a() {
18734         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18735         local fsz=`stat -c %s $DIR/$tfile`
18736         cancel_lru_locks mdc
18737
18738         # do not return layout in getattr intent
18739 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18740         $LCTL set_param fail_loc=0x170
18741         local sz=`stat -c %s $DIR/$tfile`
18742
18743         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18744
18745         rm -rf $DIR/$tfile
18746 }
18747 run_test 207a "can refresh layout at glimpse"
18748
18749 test_207b() {
18750         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18751         local cksum=`md5sum $DIR/$tfile`
18752         local fsz=`stat -c %s $DIR/$tfile`
18753         cancel_lru_locks mdc
18754         cancel_lru_locks osc
18755
18756         # do not return layout in getattr intent
18757 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18758         $LCTL set_param fail_loc=0x171
18759
18760         # it will refresh layout after the file is opened but before read issues
18761         echo checksum is "$cksum"
18762         echo "$cksum" |md5sum -c --quiet || error "file differs"
18763
18764         rm -rf $DIR/$tfile
18765 }
18766 run_test 207b "can refresh layout at open"
18767
18768 test_208() {
18769         # FIXME: in this test suite, only RD lease is used. This is okay
18770         # for now as only exclusive open is supported. After generic lease
18771         # is done, this test suite should be revised. - Jinshan
18772
18773         remote_mds_nodsh && skip "remote MDS with nodsh"
18774         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18775                 skip "Need MDS version at least 2.4.52"
18776
18777         echo "==== test 1: verify get lease work"
18778         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18779
18780         echo "==== test 2: verify lease can be broken by upcoming open"
18781         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18782         local PID=$!
18783         sleep 2
18784
18785         $MULTIOP $DIR/$tfile oO_RDWR:c
18786         kill -USR1 $PID && wait $PID || error "break lease error"
18787
18788         echo "==== test 3: verify lease can't be granted if an open already exists"
18789         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18790         local PID=$!
18791         sleep 2
18792
18793         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18794         kill -USR1 $PID && wait $PID || error "open file error"
18795
18796         echo "==== test 4: lease can sustain over recovery"
18797         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18798         PID=$!
18799         sleep 2
18800
18801         fail mds1
18802
18803         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18804
18805         echo "==== test 5: lease broken can't be regained by replay"
18806         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18807         PID=$!
18808         sleep 2
18809
18810         # open file to break lease and then recovery
18811         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18812         fail mds1
18813
18814         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18815
18816         rm -f $DIR/$tfile
18817 }
18818 run_test 208 "Exclusive open"
18819
18820 test_209() {
18821         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18822                 skip_env "must have disp_stripe"
18823
18824         touch $DIR/$tfile
18825         sync; sleep 5; sync;
18826
18827         echo 3 > /proc/sys/vm/drop_caches
18828         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18829                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18830         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18831
18832         # open/close 500 times
18833         for i in $(seq 500); do
18834                 cat $DIR/$tfile
18835         done
18836
18837         echo 3 > /proc/sys/vm/drop_caches
18838         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18839                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18840         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18841
18842         echo "before: $req_before, after: $req_after"
18843         [ $((req_after - req_before)) -ge 300 ] &&
18844                 error "open/close requests are not freed"
18845         return 0
18846 }
18847 run_test 209 "read-only open/close requests should be freed promptly"
18848
18849 test_210() {
18850         local pid
18851
18852         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18853         pid=$!
18854         sleep 1
18855
18856         $LFS getstripe $DIR/$tfile
18857         kill -USR1 $pid
18858         wait $pid || error "multiop failed"
18859
18860         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18861         pid=$!
18862         sleep 1
18863
18864         $LFS getstripe $DIR/$tfile
18865         kill -USR1 $pid
18866         wait $pid || error "multiop failed"
18867 }
18868 run_test 210 "lfs getstripe does not break leases"
18869
18870 test_212() {
18871         size=`date +%s`
18872         size=$((size % 8192 + 1))
18873         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18874         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18875         rm -f $DIR/f212 $DIR/f212.xyz
18876 }
18877 run_test 212 "Sendfile test ============================================"
18878
18879 test_213() {
18880         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18881         cancel_lru_locks osc
18882         lctl set_param fail_loc=0x8000040f
18883         # generate a read lock
18884         cat $DIR/$tfile > /dev/null
18885         # write to the file, it will try to cancel the above read lock.
18886         cat /etc/hosts >> $DIR/$tfile
18887 }
18888 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18889
18890 test_214() { # for bug 20133
18891         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18892         for (( i=0; i < 340; i++ )) ; do
18893                 touch $DIR/$tdir/d214c/a$i
18894         done
18895
18896         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18897         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18898         ls $DIR/d214c || error "ls $DIR/d214c failed"
18899         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18900         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18901 }
18902 run_test 214 "hash-indexed directory test - bug 20133"
18903
18904 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18905 create_lnet_proc_files() {
18906         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18907 }
18908
18909 # counterpart of create_lnet_proc_files
18910 remove_lnet_proc_files() {
18911         rm -f $TMP/lnet_$1.sys
18912 }
18913
18914 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18915 # 3rd arg as regexp for body
18916 check_lnet_proc_stats() {
18917         local l=$(cat "$TMP/lnet_$1" |wc -l)
18918         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18919
18920         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18921 }
18922
18923 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18924 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18925 # optional and can be regexp for 2nd line (lnet.routes case)
18926 check_lnet_proc_entry() {
18927         local blp=2          # blp stands for 'position of 1st line of body'
18928         [ -z "$5" ] || blp=3 # lnet.routes case
18929
18930         local l=$(cat "$TMP/lnet_$1" |wc -l)
18931         # subtracting one from $blp because the body can be empty
18932         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18933
18934         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18935                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18936
18937         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18938                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18939
18940         # bail out if any unexpected line happened
18941         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18942         [ "$?" != 0 ] || error "$2 misformatted"
18943 }
18944
18945 test_215() { # for bugs 18102, 21079, 21517
18946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18947
18948         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18949         local P='[1-9][0-9]*'           # positive numeric
18950         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18951         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18952         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18953         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18954
18955         local L1 # regexp for 1st line
18956         local L2 # regexp for 2nd line (optional)
18957         local BR # regexp for the rest (body)
18958
18959         # lnet.stats should look as 11 space-separated non-negative numerics
18960         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18961         create_lnet_proc_files "stats"
18962         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18963         remove_lnet_proc_files "stats"
18964
18965         # lnet.routes should look like this:
18966         # Routing disabled/enabled
18967         # net hops priority state router
18968         # where net is a string like tcp0, hops > 0, priority >= 0,
18969         # state is up/down,
18970         # router is a string like 192.168.1.1@tcp2
18971         L1="^Routing (disabled|enabled)$"
18972         L2="^net +hops +priority +state +router$"
18973         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18974         create_lnet_proc_files "routes"
18975         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18976         remove_lnet_proc_files "routes"
18977
18978         # lnet.routers should look like this:
18979         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18980         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18981         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18982         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18983         L1="^ref +rtr_ref +alive +router$"
18984         BR="^$P +$P +(up|down) +$NID$"
18985         create_lnet_proc_files "routers"
18986         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18987         remove_lnet_proc_files "routers"
18988
18989         # lnet.peers should look like this:
18990         # nid refs state last max rtr min tx min queue
18991         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18992         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18993         # numeric (0 or >0 or <0), queue >= 0.
18994         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18995         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18996         create_lnet_proc_files "peers"
18997         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18998         remove_lnet_proc_files "peers"
18999
19000         # lnet.buffers  should look like this:
19001         # pages count credits min
19002         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19003         L1="^pages +count +credits +min$"
19004         BR="^ +$N +$N +$I +$I$"
19005         create_lnet_proc_files "buffers"
19006         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19007         remove_lnet_proc_files "buffers"
19008
19009         # lnet.nis should look like this:
19010         # nid status alive refs peer rtr max tx min
19011         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19012         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19013         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19014         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19015         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19016         create_lnet_proc_files "nis"
19017         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19018         remove_lnet_proc_files "nis"
19019
19020         # can we successfully write to lnet.stats?
19021         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19022 }
19023 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19024
19025 test_216() { # bug 20317
19026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19027         remote_ost_nodsh && skip "remote OST with nodsh"
19028
19029         local node
19030         local facets=$(get_facets OST)
19031         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19032
19033         save_lustre_params client "osc.*.contention_seconds" > $p
19034         save_lustre_params $facets \
19035                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19036         save_lustre_params $facets \
19037                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19038         save_lustre_params $facets \
19039                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19040         clear_stats osc.*.osc_stats
19041
19042         # agressive lockless i/o settings
19043         do_nodes $(comma_list $(osts_nodes)) \
19044                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19045                         ldlm.namespaces.filter-*.contended_locks=0 \
19046                         ldlm.namespaces.filter-*.contention_seconds=60"
19047         lctl set_param -n osc.*.contention_seconds=60
19048
19049         $DIRECTIO write $DIR/$tfile 0 10 4096
19050         $CHECKSTAT -s 40960 $DIR/$tfile
19051
19052         # disable lockless i/o
19053         do_nodes $(comma_list $(osts_nodes)) \
19054                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19055                         ldlm.namespaces.filter-*.contended_locks=32 \
19056                         ldlm.namespaces.filter-*.contention_seconds=0"
19057         lctl set_param -n osc.*.contention_seconds=0
19058         clear_stats osc.*.osc_stats
19059
19060         dd if=/dev/zero of=$DIR/$tfile count=0
19061         $CHECKSTAT -s 0 $DIR/$tfile
19062
19063         restore_lustre_params <$p
19064         rm -f $p
19065         rm $DIR/$tfile
19066 }
19067 run_test 216 "check lockless direct write updates file size and kms correctly"
19068
19069 test_217() { # bug 22430
19070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19071
19072         local node
19073         local nid
19074
19075         for node in $(nodes_list); do
19076                 nid=$(host_nids_address $node $NETTYPE)
19077                 if [[ $nid = *-* ]] ; then
19078                         echo "lctl ping $(h2nettype $nid)"
19079                         lctl ping $(h2nettype $nid)
19080                 else
19081                         echo "skipping $node (no hyphen detected)"
19082                 fi
19083         done
19084 }
19085 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19086
19087 test_218() {
19088        # do directio so as not to populate the page cache
19089        log "creating a 10 Mb file"
19090        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19091        log "starting reads"
19092        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19093        log "truncating the file"
19094        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19095        log "killing dd"
19096        kill %+ || true # reads might have finished
19097        echo "wait until dd is finished"
19098        wait
19099        log "removing the temporary file"
19100        rm -rf $DIR/$tfile || error "tmp file removal failed"
19101 }
19102 run_test 218 "parallel read and truncate should not deadlock"
19103
19104 test_219() {
19105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19106
19107         # write one partial page
19108         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19109         # set no grant so vvp_io_commit_write will do sync write
19110         $LCTL set_param fail_loc=0x411
19111         # write a full page at the end of file
19112         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19113
19114         $LCTL set_param fail_loc=0
19115         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19116         $LCTL set_param fail_loc=0x411
19117         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19118
19119         # LU-4201
19120         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19121         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19122 }
19123 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19124
19125 test_220() { #LU-325
19126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19127         remote_ost_nodsh && skip "remote OST with nodsh"
19128         remote_mds_nodsh && skip "remote MDS with nodsh"
19129         remote_mgs_nodsh && skip "remote MGS with nodsh"
19130
19131         local OSTIDX=0
19132
19133         # create on MDT0000 so the last_id and next_id are correct
19134         mkdir_on_mdt0 $DIR/$tdir
19135         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19136         OST=${OST%_UUID}
19137
19138         # on the mdt's osc
19139         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19140         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19141                         osp.$mdtosc_proc1.prealloc_last_id)
19142         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19143                         osp.$mdtosc_proc1.prealloc_next_id)
19144
19145         $LFS df -i
19146
19147         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19148         #define OBD_FAIL_OST_ENOINO              0x229
19149         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19150         create_pool $FSNAME.$TESTNAME || return 1
19151         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19152
19153         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19154
19155         MDSOBJS=$((last_id - next_id))
19156         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19157
19158         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19159         echo "OST still has $count kbytes free"
19160
19161         echo "create $MDSOBJS files @next_id..."
19162         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19163
19164         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19165                         osp.$mdtosc_proc1.prealloc_last_id)
19166         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19167                         osp.$mdtosc_proc1.prealloc_next_id)
19168
19169         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19170         $LFS df -i
19171
19172         echo "cleanup..."
19173
19174         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19175         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19176
19177         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19178                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19179         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19180                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19181         echo "unlink $MDSOBJS files @$next_id..."
19182         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19183 }
19184 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19185
19186 test_221() {
19187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19188
19189         dd if=`which date` of=$MOUNT/date oflag=sync
19190         chmod +x $MOUNT/date
19191
19192         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19193         $LCTL set_param fail_loc=0x80001401
19194
19195         $MOUNT/date > /dev/null
19196         rm -f $MOUNT/date
19197 }
19198 run_test 221 "make sure fault and truncate race to not cause OOM"
19199
19200 test_222a () {
19201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19202
19203         rm -rf $DIR/$tdir
19204         test_mkdir $DIR/$tdir
19205         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19206         createmany -o $DIR/$tdir/$tfile 10
19207         cancel_lru_locks mdc
19208         cancel_lru_locks osc
19209         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19210         $LCTL set_param fail_loc=0x31a
19211         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19212         $LCTL set_param fail_loc=0
19213         rm -r $DIR/$tdir
19214 }
19215 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19216
19217 test_222b () {
19218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19219
19220         rm -rf $DIR/$tdir
19221         test_mkdir $DIR/$tdir
19222         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19223         createmany -o $DIR/$tdir/$tfile 10
19224         cancel_lru_locks mdc
19225         cancel_lru_locks osc
19226         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19227         $LCTL set_param fail_loc=0x31a
19228         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19229         $LCTL set_param fail_loc=0
19230 }
19231 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19232
19233 test_223 () {
19234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19235
19236         rm -rf $DIR/$tdir
19237         test_mkdir $DIR/$tdir
19238         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19239         createmany -o $DIR/$tdir/$tfile 10
19240         cancel_lru_locks mdc
19241         cancel_lru_locks osc
19242         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19243         $LCTL set_param fail_loc=0x31b
19244         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19245         $LCTL set_param fail_loc=0
19246         rm -r $DIR/$tdir
19247 }
19248 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19249
19250 test_224a() { # LU-1039, MRP-303
19251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19252         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19253         $LCTL set_param fail_loc=0x508
19254         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19255         $LCTL set_param fail_loc=0
19256         df $DIR
19257 }
19258 run_test 224a "Don't panic on bulk IO failure"
19259
19260 test_224bd_sub() { # LU-1039, MRP-303
19261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19262         local timeout=$1
19263
19264         shift
19265         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19266
19267         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19268
19269         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19270         cancel_lru_locks osc
19271         set_checksums 0
19272         stack_trap "set_checksums $ORIG_CSUM" EXIT
19273         local at_max_saved=0
19274
19275         # adaptive timeouts may prevent seeing the issue
19276         if at_is_enabled; then
19277                 at_max_saved=$(at_max_get mds)
19278                 at_max_set 0 mds client
19279                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19280         fi
19281
19282         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19283         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19284         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19285
19286         do_facet ost1 $LCTL set_param fail_loc=0
19287         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19288         df $DIR
19289 }
19290
19291 test_224b() {
19292         test_224bd_sub 3 error "dd failed"
19293 }
19294 run_test 224b "Don't panic on bulk IO failure"
19295
19296 test_224c() { # LU-6441
19297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19298         remote_mds_nodsh && skip "remote MDS with nodsh"
19299
19300         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19301         save_writethrough $p
19302         set_cache writethrough on
19303
19304         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19305         local at_max=$($LCTL get_param -n at_max)
19306         local timeout=$($LCTL get_param -n timeout)
19307         local test_at="at_max"
19308         local param_at="$FSNAME.sys.at_max"
19309         local test_timeout="timeout"
19310         local param_timeout="$FSNAME.sys.timeout"
19311
19312         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19313
19314         set_persistent_param_and_check client "$test_at" "$param_at" 0
19315         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19316
19317         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19318         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19319         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19320         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19321         sync
19322         do_facet ost1 "$LCTL set_param fail_loc=0"
19323
19324         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19325         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19326                 $timeout
19327
19328         $LCTL set_param -n $pages_per_rpc
19329         restore_lustre_params < $p
19330         rm -f $p
19331 }
19332 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19333
19334 test_224d() { # LU-11169
19335         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19336 }
19337 run_test 224d "Don't corrupt data on bulk IO timeout"
19338
19339 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19340 test_225a () {
19341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19342         if [ -z ${MDSSURVEY} ]; then
19343                 skip_env "mds-survey not found"
19344         fi
19345         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19346                 skip "Need MDS version at least 2.2.51"
19347
19348         local mds=$(facet_host $SINGLEMDS)
19349         local target=$(do_nodes $mds 'lctl dl' |
19350                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19351
19352         local cmd1="file_count=1000 thrhi=4"
19353         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19354         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19355         local cmd="$cmd1 $cmd2 $cmd3"
19356
19357         rm -f ${TMP}/mds_survey*
19358         echo + $cmd
19359         eval $cmd || error "mds-survey with zero-stripe failed"
19360         cat ${TMP}/mds_survey*
19361         rm -f ${TMP}/mds_survey*
19362 }
19363 run_test 225a "Metadata survey sanity with zero-stripe"
19364
19365 test_225b () {
19366         if [ -z ${MDSSURVEY} ]; then
19367                 skip_env "mds-survey not found"
19368         fi
19369         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19370                 skip "Need MDS version at least 2.2.51"
19371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19372         remote_mds_nodsh && skip "remote MDS with nodsh"
19373         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19374                 skip_env "Need to mount OST to test"
19375         fi
19376
19377         local mds=$(facet_host $SINGLEMDS)
19378         local target=$(do_nodes $mds 'lctl dl' |
19379                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19380
19381         local cmd1="file_count=1000 thrhi=4"
19382         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19383         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19384         local cmd="$cmd1 $cmd2 $cmd3"
19385
19386         rm -f ${TMP}/mds_survey*
19387         echo + $cmd
19388         eval $cmd || error "mds-survey with stripe_count failed"
19389         cat ${TMP}/mds_survey*
19390         rm -f ${TMP}/mds_survey*
19391 }
19392 run_test 225b "Metadata survey sanity with stripe_count = 1"
19393
19394 mcreate_path2fid () {
19395         local mode=$1
19396         local major=$2
19397         local minor=$3
19398         local name=$4
19399         local desc=$5
19400         local path=$DIR/$tdir/$name
19401         local fid
19402         local rc
19403         local fid_path
19404
19405         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19406                 error "cannot create $desc"
19407
19408         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19409         rc=$?
19410         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19411
19412         fid_path=$($LFS fid2path $MOUNT $fid)
19413         rc=$?
19414         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19415
19416         [ "$path" == "$fid_path" ] ||
19417                 error "fid2path returned $fid_path, expected $path"
19418
19419         echo "pass with $path and $fid"
19420 }
19421
19422 test_226a () {
19423         rm -rf $DIR/$tdir
19424         mkdir -p $DIR/$tdir
19425
19426         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19427         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19428         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19429         mcreate_path2fid 0040666 0 0 dir "directory"
19430         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19431         mcreate_path2fid 0100666 0 0 file "regular file"
19432         mcreate_path2fid 0120666 0 0 link "symbolic link"
19433         mcreate_path2fid 0140666 0 0 sock "socket"
19434 }
19435 run_test 226a "call path2fid and fid2path on files of all type"
19436
19437 test_226b () {
19438         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19439
19440         local MDTIDX=1
19441
19442         rm -rf $DIR/$tdir
19443         mkdir -p $DIR/$tdir
19444         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19445                 error "create remote directory failed"
19446         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19447         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19448                                 "character special file (null)"
19449         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19450                                 "character special file (no device)"
19451         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19452         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19453                                 "block special file (loop)"
19454         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19455         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19456         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19457 }
19458 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19459
19460 test_226c () {
19461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19462         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19463                 skip "Need MDS version at least 2.13.55"
19464
19465         local submnt=/mnt/submnt
19466         local srcfile=/etc/passwd
19467         local dstfile=$submnt/passwd
19468         local path
19469         local fid
19470
19471         rm -rf $DIR/$tdir
19472         rm -rf $submnt
19473         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19474                 error "create remote directory failed"
19475         mkdir -p $submnt || error "create $submnt failed"
19476         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19477                 error "mount $submnt failed"
19478         stack_trap "umount $submnt" EXIT
19479
19480         cp $srcfile $dstfile
19481         fid=$($LFS path2fid $dstfile)
19482         path=$($LFS fid2path $submnt "$fid")
19483         [ "$path" = "$dstfile" ] ||
19484                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19485 }
19486 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19487
19488 # LU-1299 Executing or running ldd on a truncated executable does not
19489 # cause an out-of-memory condition.
19490 test_227() {
19491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19492         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19493
19494         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19495         chmod +x $MOUNT/date
19496
19497         $MOUNT/date > /dev/null
19498         ldd $MOUNT/date > /dev/null
19499         rm -f $MOUNT/date
19500 }
19501 run_test 227 "running truncated executable does not cause OOM"
19502
19503 # LU-1512 try to reuse idle OI blocks
19504 test_228a() {
19505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19506         remote_mds_nodsh && skip "remote MDS with nodsh"
19507         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19508
19509         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19510         local myDIR=$DIR/$tdir
19511
19512         mkdir -p $myDIR
19513         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19514         $LCTL set_param fail_loc=0x80001002
19515         createmany -o $myDIR/t- 10000
19516         $LCTL set_param fail_loc=0
19517         # The guard is current the largest FID holder
19518         touch $myDIR/guard
19519         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19520                     tr -d '[')
19521         local IDX=$(($SEQ % 64))
19522
19523         do_facet $SINGLEMDS sync
19524         # Make sure journal flushed.
19525         sleep 6
19526         local blk1=$(do_facet $SINGLEMDS \
19527                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19528                      grep Blockcount | awk '{print $4}')
19529
19530         # Remove old files, some OI blocks will become idle.
19531         unlinkmany $myDIR/t- 10000
19532         # Create new files, idle OI blocks should be reused.
19533         createmany -o $myDIR/t- 2000
19534         do_facet $SINGLEMDS sync
19535         # Make sure journal flushed.
19536         sleep 6
19537         local blk2=$(do_facet $SINGLEMDS \
19538                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19539                      grep Blockcount | awk '{print $4}')
19540
19541         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19542 }
19543 run_test 228a "try to reuse idle OI blocks"
19544
19545 test_228b() {
19546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19547         remote_mds_nodsh && skip "remote MDS with nodsh"
19548         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19549
19550         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19551         local myDIR=$DIR/$tdir
19552
19553         mkdir -p $myDIR
19554         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19555         $LCTL set_param fail_loc=0x80001002
19556         createmany -o $myDIR/t- 10000
19557         $LCTL set_param fail_loc=0
19558         # The guard is current the largest FID holder
19559         touch $myDIR/guard
19560         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19561                     tr -d '[')
19562         local IDX=$(($SEQ % 64))
19563
19564         do_facet $SINGLEMDS sync
19565         # Make sure journal flushed.
19566         sleep 6
19567         local blk1=$(do_facet $SINGLEMDS \
19568                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19569                      grep Blockcount | awk '{print $4}')
19570
19571         # Remove old files, some OI blocks will become idle.
19572         unlinkmany $myDIR/t- 10000
19573
19574         # stop the MDT
19575         stop $SINGLEMDS || error "Fail to stop MDT."
19576         # remount the MDT
19577         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19578                 error "Fail to start MDT."
19579
19580         df $MOUNT || error "Fail to df."
19581         # Create new files, idle OI blocks should be reused.
19582         createmany -o $myDIR/t- 2000
19583         do_facet $SINGLEMDS sync
19584         # Make sure journal flushed.
19585         sleep 6
19586         local blk2=$(do_facet $SINGLEMDS \
19587                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19588                      grep Blockcount | awk '{print $4}')
19589
19590         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19591 }
19592 run_test 228b "idle OI blocks can be reused after MDT restart"
19593
19594 #LU-1881
19595 test_228c() {
19596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19597         remote_mds_nodsh && skip "remote MDS with nodsh"
19598         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19599
19600         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19601         local myDIR=$DIR/$tdir
19602
19603         mkdir -p $myDIR
19604         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19605         $LCTL set_param fail_loc=0x80001002
19606         # 20000 files can guarantee there are index nodes in the OI file
19607         createmany -o $myDIR/t- 20000
19608         $LCTL set_param fail_loc=0
19609         # The guard is current the largest FID holder
19610         touch $myDIR/guard
19611         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19612                     tr -d '[')
19613         local IDX=$(($SEQ % 64))
19614
19615         do_facet $SINGLEMDS sync
19616         # Make sure journal flushed.
19617         sleep 6
19618         local blk1=$(do_facet $SINGLEMDS \
19619                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19620                      grep Blockcount | awk '{print $4}')
19621
19622         # Remove old files, some OI blocks will become idle.
19623         unlinkmany $myDIR/t- 20000
19624         rm -f $myDIR/guard
19625         # The OI file should become empty now
19626
19627         # Create new files, idle OI blocks should be reused.
19628         createmany -o $myDIR/t- 2000
19629         do_facet $SINGLEMDS sync
19630         # Make sure journal flushed.
19631         sleep 6
19632         local blk2=$(do_facet $SINGLEMDS \
19633                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19634                      grep Blockcount | awk '{print $4}')
19635
19636         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19637 }
19638 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19639
19640 test_229() { # LU-2482, LU-3448
19641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19642         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19643         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19644                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19645
19646         rm -f $DIR/$tfile
19647
19648         # Create a file with a released layout and stripe count 2.
19649         $MULTIOP $DIR/$tfile H2c ||
19650                 error "failed to create file with released layout"
19651
19652         $LFS getstripe -v $DIR/$tfile
19653
19654         local pattern=$($LFS getstripe -L $DIR/$tfile)
19655         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19656
19657         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19658                 error "getstripe"
19659         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19660         stat $DIR/$tfile || error "failed to stat released file"
19661
19662         chown $RUNAS_ID $DIR/$tfile ||
19663                 error "chown $RUNAS_ID $DIR/$tfile failed"
19664
19665         chgrp $RUNAS_ID $DIR/$tfile ||
19666                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19667
19668         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19669         rm $DIR/$tfile || error "failed to remove released file"
19670 }
19671 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19672
19673 test_230a() {
19674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19675         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19676         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19677                 skip "Need MDS version at least 2.11.52"
19678
19679         local MDTIDX=1
19680
19681         test_mkdir $DIR/$tdir
19682         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19683         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19684         [ $mdt_idx -ne 0 ] &&
19685                 error "create local directory on wrong MDT $mdt_idx"
19686
19687         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19688                         error "create remote directory failed"
19689         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19690         [ $mdt_idx -ne $MDTIDX ] &&
19691                 error "create remote directory on wrong MDT $mdt_idx"
19692
19693         createmany -o $DIR/$tdir/test_230/t- 10 ||
19694                 error "create files on remote directory failed"
19695         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19696         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19697         rm -r $DIR/$tdir || error "unlink remote directory failed"
19698 }
19699 run_test 230a "Create remote directory and files under the remote directory"
19700
19701 test_230b() {
19702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19703         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19704         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19705                 skip "Need MDS version at least 2.11.52"
19706
19707         local MDTIDX=1
19708         local mdt_index
19709         local i
19710         local file
19711         local pid
19712         local stripe_count
19713         local migrate_dir=$DIR/$tdir/migrate_dir
19714         local other_dir=$DIR/$tdir/other_dir
19715
19716         test_mkdir $DIR/$tdir
19717         test_mkdir -i0 -c1 $migrate_dir
19718         test_mkdir -i0 -c1 $other_dir
19719         for ((i=0; i<10; i++)); do
19720                 mkdir -p $migrate_dir/dir_${i}
19721                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19722                         error "create files under remote dir failed $i"
19723         done
19724
19725         cp /etc/passwd $migrate_dir/$tfile
19726         cp /etc/passwd $other_dir/$tfile
19727         chattr +SAD $migrate_dir
19728         chattr +SAD $migrate_dir/$tfile
19729
19730         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19731         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19732         local old_dir_mode=$(stat -c%f $migrate_dir)
19733         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19734
19735         mkdir -p $migrate_dir/dir_default_stripe2
19736         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19737         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19738
19739         mkdir -p $other_dir
19740         ln $migrate_dir/$tfile $other_dir/luna
19741         ln $migrate_dir/$tfile $migrate_dir/sofia
19742         ln $other_dir/$tfile $migrate_dir/david
19743         ln -s $migrate_dir/$tfile $other_dir/zachary
19744         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19745         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19746
19747         local len
19748         local lnktgt
19749
19750         # inline symlink
19751         for len in 58 59 60; do
19752                 lnktgt=$(str_repeat 'l' $len)
19753                 touch $migrate_dir/$lnktgt
19754                 ln -s $lnktgt $migrate_dir/${len}char_ln
19755         done
19756
19757         # PATH_MAX
19758         for len in 4094 4095; do
19759                 lnktgt=$(str_repeat 'l' $len)
19760                 ln -s $lnktgt $migrate_dir/${len}char_ln
19761         done
19762
19763         # NAME_MAX
19764         for len in 254 255; do
19765                 touch $migrate_dir/$(str_repeat 'l' $len)
19766         done
19767
19768         $LFS migrate -m $MDTIDX $migrate_dir ||
19769                 error "fails on migrating remote dir to MDT1"
19770
19771         echo "migratate to MDT1, then checking.."
19772         for ((i = 0; i < 10; i++)); do
19773                 for file in $(find $migrate_dir/dir_${i}); do
19774                         mdt_index=$($LFS getstripe -m $file)
19775                         # broken symlink getstripe will fail
19776                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19777                                 error "$file is not on MDT${MDTIDX}"
19778                 done
19779         done
19780
19781         # the multiple link file should still in MDT0
19782         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19783         [ $mdt_index == 0 ] ||
19784                 error "$file is not on MDT${MDTIDX}"
19785
19786         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19787         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19788                 error " expect $old_dir_flag get $new_dir_flag"
19789
19790         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19791         [ "$old_file_flag" = "$new_file_flag" ] ||
19792                 error " expect $old_file_flag get $new_file_flag"
19793
19794         local new_dir_mode=$(stat -c%f $migrate_dir)
19795         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19796                 error "expect mode $old_dir_mode get $new_dir_mode"
19797
19798         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19799         [ "$old_file_mode" = "$new_file_mode" ] ||
19800                 error "expect mode $old_file_mode get $new_file_mode"
19801
19802         diff /etc/passwd $migrate_dir/$tfile ||
19803                 error "$tfile different after migration"
19804
19805         diff /etc/passwd $other_dir/luna ||
19806                 error "luna different after migration"
19807
19808         diff /etc/passwd $migrate_dir/sofia ||
19809                 error "sofia different after migration"
19810
19811         diff /etc/passwd $migrate_dir/david ||
19812                 error "david different after migration"
19813
19814         diff /etc/passwd $other_dir/zachary ||
19815                 error "zachary different after migration"
19816
19817         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19818                 error "${tfile}_ln different after migration"
19819
19820         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19821                 error "${tfile}_ln_other different after migration"
19822
19823         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19824         [ $stripe_count = 2 ] ||
19825                 error "dir strpe_count $d != 2 after migration."
19826
19827         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19828         [ $stripe_count = 2 ] ||
19829                 error "file strpe_count $d != 2 after migration."
19830
19831         #migrate back to MDT0
19832         MDTIDX=0
19833
19834         $LFS migrate -m $MDTIDX $migrate_dir ||
19835                 error "fails on migrating remote dir to MDT0"
19836
19837         echo "migrate back to MDT0, checking.."
19838         for file in $(find $migrate_dir); do
19839                 mdt_index=$($LFS getstripe -m $file)
19840                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19841                         error "$file is not on MDT${MDTIDX}"
19842         done
19843
19844         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19845         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19846                 error " expect $old_dir_flag get $new_dir_flag"
19847
19848         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19849         [ "$old_file_flag" = "$new_file_flag" ] ||
19850                 error " expect $old_file_flag get $new_file_flag"
19851
19852         local new_dir_mode=$(stat -c%f $migrate_dir)
19853         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19854                 error "expect mode $old_dir_mode get $new_dir_mode"
19855
19856         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19857         [ "$old_file_mode" = "$new_file_mode" ] ||
19858                 error "expect mode $old_file_mode get $new_file_mode"
19859
19860         diff /etc/passwd ${migrate_dir}/$tfile ||
19861                 error "$tfile different after migration"
19862
19863         diff /etc/passwd ${other_dir}/luna ||
19864                 error "luna different after migration"
19865
19866         diff /etc/passwd ${migrate_dir}/sofia ||
19867                 error "sofia different after migration"
19868
19869         diff /etc/passwd ${other_dir}/zachary ||
19870                 error "zachary different after migration"
19871
19872         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19873                 error "${tfile}_ln different after migration"
19874
19875         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19876                 error "${tfile}_ln_other different after migration"
19877
19878         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19879         [ $stripe_count = 2 ] ||
19880                 error "dir strpe_count $d != 2 after migration."
19881
19882         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19883         [ $stripe_count = 2 ] ||
19884                 error "file strpe_count $d != 2 after migration."
19885
19886         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19887 }
19888 run_test 230b "migrate directory"
19889
19890 test_230c() {
19891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19893         remote_mds_nodsh && skip "remote MDS with nodsh"
19894         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19895                 skip "Need MDS version at least 2.11.52"
19896
19897         local MDTIDX=1
19898         local total=3
19899         local mdt_index
19900         local file
19901         local migrate_dir=$DIR/$tdir/migrate_dir
19902
19903         #If migrating directory fails in the middle, all entries of
19904         #the directory is still accessiable.
19905         test_mkdir $DIR/$tdir
19906         test_mkdir -i0 -c1 $migrate_dir
19907         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19908         stat $migrate_dir
19909         createmany -o $migrate_dir/f $total ||
19910                 error "create files under ${migrate_dir} failed"
19911
19912         # fail after migrating top dir, and this will fail only once, so the
19913         # first sub file migration will fail (currently f3), others succeed.
19914         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19915         do_facet mds1 lctl set_param fail_loc=0x1801
19916         local t=$(ls $migrate_dir | wc -l)
19917         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19918                 error "migrate should fail"
19919         local u=$(ls $migrate_dir | wc -l)
19920         [ "$u" == "$t" ] || error "$u != $t during migration"
19921
19922         # add new dir/file should succeed
19923         mkdir $migrate_dir/dir ||
19924                 error "mkdir failed under migrating directory"
19925         touch $migrate_dir/file ||
19926                 error "create file failed under migrating directory"
19927
19928         # add file with existing name should fail
19929         for file in $migrate_dir/f*; do
19930                 stat $file > /dev/null || error "stat $file failed"
19931                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19932                         error "open(O_CREAT|O_EXCL) $file should fail"
19933                 $MULTIOP $file m && error "create $file should fail"
19934                 touch $DIR/$tdir/remote_dir/$tfile ||
19935                         error "touch $tfile failed"
19936                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19937                         error "link $file should fail"
19938                 mdt_index=$($LFS getstripe -m $file)
19939                 if [ $mdt_index == 0 ]; then
19940                         # file failed to migrate is not allowed to rename to
19941                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19942                                 error "rename to $file should fail"
19943                 else
19944                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19945                                 error "rename to $file failed"
19946                 fi
19947                 echo hello >> $file || error "write $file failed"
19948         done
19949
19950         # resume migration with different options should fail
19951         $LFS migrate -m 0 $migrate_dir &&
19952                 error "migrate -m 0 $migrate_dir should fail"
19953
19954         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19955                 error "migrate -c 2 $migrate_dir should fail"
19956
19957         # resume migration should succeed
19958         $LFS migrate -m $MDTIDX $migrate_dir ||
19959                 error "migrate $migrate_dir failed"
19960
19961         echo "Finish migration, then checking.."
19962         for file in $(find $migrate_dir); do
19963                 mdt_index=$($LFS getstripe -m $file)
19964                 [ $mdt_index == $MDTIDX ] ||
19965                         error "$file is not on MDT${MDTIDX}"
19966         done
19967
19968         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19969 }
19970 run_test 230c "check directory accessiblity if migration failed"
19971
19972 test_230d() {
19973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19974         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19975         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19976                 skip "Need MDS version at least 2.11.52"
19977         # LU-11235
19978         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19979
19980         local migrate_dir=$DIR/$tdir/migrate_dir
19981         local old_index
19982         local new_index
19983         local old_count
19984         local new_count
19985         local new_hash
19986         local mdt_index
19987         local i
19988         local j
19989
19990         old_index=$((RANDOM % MDSCOUNT))
19991         old_count=$((MDSCOUNT - old_index))
19992         new_index=$((RANDOM % MDSCOUNT))
19993         new_count=$((MDSCOUNT - new_index))
19994         new_hash=1 # for all_char
19995
19996         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19997         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19998
19999         test_mkdir $DIR/$tdir
20000         test_mkdir -i $old_index -c $old_count $migrate_dir
20001
20002         for ((i=0; i<100; i++)); do
20003                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20004                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20005                         error "create files under remote dir failed $i"
20006         done
20007
20008         echo -n "Migrate from MDT$old_index "
20009         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20010         echo -n "to MDT$new_index"
20011         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20012         echo
20013
20014         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20015         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20016                 error "migrate remote dir error"
20017
20018         echo "Finish migration, then checking.."
20019         for file in $(find $migrate_dir -maxdepth 1); do
20020                 mdt_index=$($LFS getstripe -m $file)
20021                 if [ $mdt_index -lt $new_index ] ||
20022                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20023                         error "$file is on MDT$mdt_index"
20024                 fi
20025         done
20026
20027         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20028 }
20029 run_test 230d "check migrate big directory"
20030
20031 test_230e() {
20032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20033         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20034         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20035                 skip "Need MDS version at least 2.11.52"
20036
20037         local i
20038         local j
20039         local a_fid
20040         local b_fid
20041
20042         mkdir_on_mdt0 $DIR/$tdir
20043         mkdir $DIR/$tdir/migrate_dir
20044         mkdir $DIR/$tdir/other_dir
20045         touch $DIR/$tdir/migrate_dir/a
20046         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20047         ls $DIR/$tdir/other_dir
20048
20049         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20050                 error "migrate dir fails"
20051
20052         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20053         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20054
20055         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20056         [ $mdt_index == 0 ] || error "a is not on MDT0"
20057
20058         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20059                 error "migrate dir fails"
20060
20061         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20062         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20063
20064         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20065         [ $mdt_index == 1 ] || error "a is not on MDT1"
20066
20067         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20068         [ $mdt_index == 1 ] || error "b is not on MDT1"
20069
20070         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20071         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20072
20073         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20074
20075         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20076 }
20077 run_test 230e "migrate mulitple local link files"
20078
20079 test_230f() {
20080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20081         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20082         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20083                 skip "Need MDS version at least 2.11.52"
20084
20085         local a_fid
20086         local ln_fid
20087
20088         mkdir -p $DIR/$tdir
20089         mkdir $DIR/$tdir/migrate_dir
20090         $LFS mkdir -i1 $DIR/$tdir/other_dir
20091         touch $DIR/$tdir/migrate_dir/a
20092         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20093         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20094         ls $DIR/$tdir/other_dir
20095
20096         # a should be migrated to MDT1, since no other links on MDT0
20097         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20098                 error "#1 migrate dir fails"
20099         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20100         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20101         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20102         [ $mdt_index == 1 ] || error "a is not on MDT1"
20103
20104         # a should stay on MDT1, because it is a mulitple link file
20105         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20106                 error "#2 migrate dir fails"
20107         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20108         [ $mdt_index == 1 ] || error "a is not on MDT1"
20109
20110         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20111                 error "#3 migrate dir fails"
20112
20113         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20114         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20115         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20116
20117         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20118         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20119
20120         # a should be migrated to MDT0, since no other links on MDT1
20121         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20122                 error "#4 migrate dir fails"
20123         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20124         [ $mdt_index == 0 ] || error "a is not on MDT0"
20125
20126         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20127 }
20128 run_test 230f "migrate mulitple remote link files"
20129
20130 test_230g() {
20131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20132         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20133         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20134                 skip "Need MDS version at least 2.11.52"
20135
20136         mkdir -p $DIR/$tdir/migrate_dir
20137
20138         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20139                 error "migrating dir to non-exist MDT succeeds"
20140         true
20141 }
20142 run_test 230g "migrate dir to non-exist MDT"
20143
20144 test_230h() {
20145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20147         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20148                 skip "Need MDS version at least 2.11.52"
20149
20150         local mdt_index
20151
20152         mkdir -p $DIR/$tdir/migrate_dir
20153
20154         $LFS migrate -m1 $DIR &&
20155                 error "migrating mountpoint1 should fail"
20156
20157         $LFS migrate -m1 $DIR/$tdir/.. &&
20158                 error "migrating mountpoint2 should fail"
20159
20160         # same as mv
20161         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20162                 error "migrating $tdir/migrate_dir/.. should fail"
20163
20164         true
20165 }
20166 run_test 230h "migrate .. and root"
20167
20168 test_230i() {
20169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20170         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20171         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20172                 skip "Need MDS version at least 2.11.52"
20173
20174         mkdir -p $DIR/$tdir/migrate_dir
20175
20176         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20177                 error "migration fails with a tailing slash"
20178
20179         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20180                 error "migration fails with two tailing slashes"
20181 }
20182 run_test 230i "lfs migrate -m tolerates trailing slashes"
20183
20184 test_230j() {
20185         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20186         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20187                 skip "Need MDS version at least 2.11.52"
20188
20189         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20190         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20191                 error "create $tfile failed"
20192         cat /etc/passwd > $DIR/$tdir/$tfile
20193
20194         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20195
20196         cmp /etc/passwd $DIR/$tdir/$tfile ||
20197                 error "DoM file mismatch after migration"
20198 }
20199 run_test 230j "DoM file data not changed after dir migration"
20200
20201 test_230k() {
20202         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20203         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20204                 skip "Need MDS version at least 2.11.56"
20205
20206         local total=20
20207         local files_on_starting_mdt=0
20208
20209         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20210         $LFS getdirstripe $DIR/$tdir
20211         for i in $(seq $total); do
20212                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20213                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20214                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20215         done
20216
20217         echo "$files_on_starting_mdt files on MDT0"
20218
20219         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20220         $LFS getdirstripe $DIR/$tdir
20221
20222         files_on_starting_mdt=0
20223         for i in $(seq $total); do
20224                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20225                         error "file $tfile.$i mismatch after migration"
20226                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20227                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20228         done
20229
20230         echo "$files_on_starting_mdt files on MDT1 after migration"
20231         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20232
20233         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20234         $LFS getdirstripe $DIR/$tdir
20235
20236         files_on_starting_mdt=0
20237         for i in $(seq $total); do
20238                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20239                         error "file $tfile.$i mismatch after 2nd migration"
20240                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20241                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20242         done
20243
20244         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20245         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20246
20247         true
20248 }
20249 run_test 230k "file data not changed after dir migration"
20250
20251 test_230l() {
20252         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20253         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20254                 skip "Need MDS version at least 2.11.56"
20255
20256         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20257         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20258                 error "create files under remote dir failed $i"
20259         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20260 }
20261 run_test 230l "readdir between MDTs won't crash"
20262
20263 test_230m() {
20264         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20265         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20266                 skip "Need MDS version at least 2.11.56"
20267
20268         local MDTIDX=1
20269         local mig_dir=$DIR/$tdir/migrate_dir
20270         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20271         local shortstr="b"
20272         local val
20273
20274         echo "Creating files and dirs with xattrs"
20275         test_mkdir $DIR/$tdir
20276         test_mkdir -i0 -c1 $mig_dir
20277         mkdir $mig_dir/dir
20278         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20279                 error "cannot set xattr attr1 on dir"
20280         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20281                 error "cannot set xattr attr2 on dir"
20282         touch $mig_dir/dir/f0
20283         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20284                 error "cannot set xattr attr1 on file"
20285         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20286                 error "cannot set xattr attr2 on file"
20287         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20288         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20289         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20290         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20291         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20292         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20293         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20294         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20295         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20296
20297         echo "Migrating to MDT1"
20298         $LFS migrate -m $MDTIDX $mig_dir ||
20299                 error "fails on migrating dir to MDT1"
20300
20301         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20302         echo "Checking xattrs"
20303         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20304         [ "$val" = $longstr ] ||
20305                 error "expecting xattr1 $longstr on dir, found $val"
20306         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20307         [ "$val" = $shortstr ] ||
20308                 error "expecting xattr2 $shortstr on dir, found $val"
20309         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20310         [ "$val" = $longstr ] ||
20311                 error "expecting xattr1 $longstr on file, found $val"
20312         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20313         [ "$val" = $shortstr ] ||
20314                 error "expecting xattr2 $shortstr on file, found $val"
20315 }
20316 run_test 230m "xattrs not changed after dir migration"
20317
20318 test_230n() {
20319         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20320         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20321                 skip "Need MDS version at least 2.13.53"
20322
20323         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20324         cat /etc/hosts > $DIR/$tdir/$tfile
20325         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20326         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20327
20328         cmp /etc/hosts $DIR/$tdir/$tfile ||
20329                 error "File data mismatch after migration"
20330 }
20331 run_test 230n "Dir migration with mirrored file"
20332
20333 test_230o() {
20334         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20335         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20336                 skip "Need MDS version at least 2.13.52"
20337
20338         local mdts=$(comma_list $(mdts_nodes))
20339         local timeout=100
20340         local restripe_status
20341         local delta
20342         local i
20343
20344         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20345
20346         # in case "crush" hash type is not set
20347         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20348
20349         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20350                            mdt.*MDT0000.enable_dir_restripe)
20351         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20352         stack_trap "do_nodes $mdts $LCTL set_param \
20353                     mdt.*.enable_dir_restripe=$restripe_status"
20354
20355         mkdir $DIR/$tdir
20356         createmany -m $DIR/$tdir/f 100 ||
20357                 error "create files under remote dir failed $i"
20358         createmany -d $DIR/$tdir/d 100 ||
20359                 error "create dirs under remote dir failed $i"
20360
20361         for i in $(seq 2 $MDSCOUNT); do
20362                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20363                 $LFS setdirstripe -c $i $DIR/$tdir ||
20364                         error "split -c $i $tdir failed"
20365                 wait_update $HOSTNAME \
20366                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20367                         error "dir split not finished"
20368                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20369                         awk '/migrate/ {sum += $2} END { print sum }')
20370                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20371                 # delta is around total_files/stripe_count
20372                 (( $delta < 200 / (i - 1) + 4 )) ||
20373                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20374         done
20375 }
20376 run_test 230o "dir split"
20377
20378 test_230p() {
20379         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20380         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20381                 skip "Need MDS version at least 2.13.52"
20382
20383         local mdts=$(comma_list $(mdts_nodes))
20384         local timeout=100
20385         local restripe_status
20386         local delta
20387         local c
20388
20389         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20390
20391         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20392
20393         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20394                            mdt.*MDT0000.enable_dir_restripe)
20395         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20396         stack_trap "do_nodes $mdts $LCTL set_param \
20397                     mdt.*.enable_dir_restripe=$restripe_status"
20398
20399         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20400         createmany -m $DIR/$tdir/f 100 ||
20401                 error "create files under remote dir failed"
20402         createmany -d $DIR/$tdir/d 100 ||
20403                 error "create dirs under remote dir failed"
20404
20405         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20406                 local mdt_hash="crush"
20407
20408                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20409                 $LFS setdirstripe -c $c $DIR/$tdir ||
20410                         error "split -c $c $tdir failed"
20411                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20412                         mdt_hash="$mdt_hash,fixed"
20413                 elif [ $c -eq 1 ]; then
20414                         mdt_hash="none"
20415                 fi
20416                 wait_update $HOSTNAME \
20417                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20418                         error "dir merge not finished"
20419                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20420                         awk '/migrate/ {sum += $2} END { print sum }')
20421                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20422                 # delta is around total_files/stripe_count
20423                 (( delta < 200 / c + 4 )) ||
20424                         error "$delta files migrated >= $((200 / c + 4))"
20425         done
20426 }
20427 run_test 230p "dir merge"
20428
20429 test_230q() {
20430         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20431         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20432                 skip "Need MDS version at least 2.13.52"
20433
20434         local mdts=$(comma_list $(mdts_nodes))
20435         local saved_threshold=$(do_facet mds1 \
20436                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20437         local saved_delta=$(do_facet mds1 \
20438                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20439         local threshold=100
20440         local delta=2
20441         local total=0
20442         local stripe_count=0
20443         local stripe_index
20444         local nr_files
20445         local create
20446
20447         # test with fewer files on ZFS
20448         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20449
20450         stack_trap "do_nodes $mdts $LCTL set_param \
20451                     mdt.*.dir_split_count=$saved_threshold"
20452         stack_trap "do_nodes $mdts $LCTL set_param \
20453                     mdt.*.dir_split_delta=$saved_delta"
20454         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20455         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20456         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20457         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20458         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20459         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20460
20461         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20462         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20463
20464         create=$((threshold * 3 / 2))
20465         while [ $stripe_count -lt $MDSCOUNT ]; do
20466                 createmany -m $DIR/$tdir/f $total $create ||
20467                         error "create sub files failed"
20468                 stat $DIR/$tdir > /dev/null
20469                 total=$((total + create))
20470                 stripe_count=$((stripe_count + delta))
20471                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20472
20473                 wait_update $HOSTNAME \
20474                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20475                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20476
20477                 wait_update $HOSTNAME \
20478                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20479                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20480
20481                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20482                 echo "$nr_files/$total files on MDT$stripe_index after split"
20483                 # allow 10% margin of imbalance with crush hash
20484                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20485                         error "$nr_files files on MDT$stripe_index after split"
20486
20487                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20488                 [ $nr_files -eq $total ] ||
20489                         error "total sub files $nr_files != $total"
20490         done
20491
20492         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20493
20494         echo "fixed layout directory won't auto split"
20495         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20496         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20497                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20498         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20499                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20500 }
20501 run_test 230q "dir auto split"
20502
20503 test_230r() {
20504         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20505         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20506         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20507                 skip "Need MDS version at least 2.13.54"
20508
20509         # maximum amount of local locks:
20510         # parent striped dir - 2 locks
20511         # new stripe in parent to migrate to - 1 lock
20512         # source and target - 2 locks
20513         # Total 5 locks for regular file
20514         mkdir -p $DIR/$tdir
20515         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20516         touch $DIR/$tdir/dir1/eee
20517
20518         # create 4 hardlink for 4 more locks
20519         # Total: 9 locks > RS_MAX_LOCKS (8)
20520         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20521         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20522         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20523         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20524         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20525         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20526         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20527         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20528
20529         cancel_lru_locks mdc
20530
20531         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20532                 error "migrate dir fails"
20533
20534         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20535 }
20536 run_test 230r "migrate with too many local locks"
20537
20538 test_230s() {
20539         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20540                 skip "Need MDS version at least 2.14.52"
20541
20542         local mdts=$(comma_list $(mdts_nodes))
20543         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20544                                 mdt.*MDT0000.enable_dir_restripe)
20545
20546         stack_trap "do_nodes $mdts $LCTL set_param \
20547                     mdt.*.enable_dir_restripe=$restripe_status"
20548
20549         local st
20550         for st in 0 1; do
20551                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20552                 test_mkdir $DIR/$tdir
20553                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20554                         error "$LFS mkdir should return EEXIST if target exists"
20555                 rmdir $DIR/$tdir
20556         done
20557 }
20558 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20559
20560 test_230t()
20561 {
20562         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20563         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20564                 skip "Need MDS version at least 2.14.50"
20565
20566         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20567         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20568         $LFS project -p 1 -s $DIR/$tdir ||
20569                 error "set $tdir project id failed"
20570         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20571                 error "set subdir project id failed"
20572         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20573 }
20574 run_test 230t "migrate directory with project ID set"
20575
20576 test_230u()
20577 {
20578         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20579         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20580                 skip "Need MDS version at least 2.14.53"
20581
20582         local count
20583
20584         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20585         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20586         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20587         for i in $(seq 0 $((MDSCOUNT - 1))); do
20588                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20589                 echo "$count dirs migrated to MDT$i"
20590         done
20591         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20592         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20593 }
20594 run_test 230u "migrate directory by QOS"
20595
20596 test_230v()
20597 {
20598         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20599         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20600                 skip "Need MDS version at least 2.14.53"
20601
20602         local count
20603
20604         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20605         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20606         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20607         for i in $(seq 0 $((MDSCOUNT - 1))); do
20608                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20609                 echo "$count subdirs migrated to MDT$i"
20610                 (( i == 3 )) && (( count > 0 )) &&
20611                         error "subdir shouldn't be migrated to MDT3"
20612         done
20613         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20614         (( count == 3 )) || error "dirs migrated to $count MDTs"
20615 }
20616 run_test 230v "subdir migrated to the MDT where its parent is located"
20617
20618 test_230w() {
20619         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20620         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20621                 skip "Need MDS version at least 2.14.53"
20622
20623         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20624
20625         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20626                 error "migrate failed"
20627
20628         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20629                 error "$tdir stripe count mismatch"
20630
20631         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20632                 error "$tdir/sub is striped"
20633 }
20634 run_test 230w "non-recursive mode dir migration"
20635
20636 test_231a()
20637 {
20638         # For simplicity this test assumes that max_pages_per_rpc
20639         # is the same across all OSCs
20640         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20641         local bulk_size=$((max_pages * PAGE_SIZE))
20642         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20643                                        head -n 1)
20644
20645         mkdir -p $DIR/$tdir
20646         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20647                 error "failed to set stripe with -S ${brw_size}M option"
20648
20649         # clear the OSC stats
20650         $LCTL set_param osc.*.stats=0 &>/dev/null
20651         stop_writeback
20652
20653         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20654         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20655                 oflag=direct &>/dev/null || error "dd failed"
20656
20657         sync; sleep 1; sync # just to be safe
20658         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20659         if [ x$nrpcs != "x1" ]; then
20660                 $LCTL get_param osc.*.stats
20661                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20662         fi
20663
20664         start_writeback
20665         # Drop the OSC cache, otherwise we will read from it
20666         cancel_lru_locks osc
20667
20668         # clear the OSC stats
20669         $LCTL set_param osc.*.stats=0 &>/dev/null
20670
20671         # Client reads $bulk_size.
20672         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20673                 iflag=direct &>/dev/null || error "dd failed"
20674
20675         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20676         if [ x$nrpcs != "x1" ]; then
20677                 $LCTL get_param osc.*.stats
20678                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20679         fi
20680 }
20681 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20682
20683 test_231b() {
20684         mkdir -p $DIR/$tdir
20685         local i
20686         for i in {0..1023}; do
20687                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20688                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20689                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20690         done
20691         sync
20692 }
20693 run_test 231b "must not assert on fully utilized OST request buffer"
20694
20695 test_232a() {
20696         mkdir -p $DIR/$tdir
20697         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20698
20699         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20700         do_facet ost1 $LCTL set_param fail_loc=0x31c
20701
20702         # ignore dd failure
20703         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20704
20705         do_facet ost1 $LCTL set_param fail_loc=0
20706         umount_client $MOUNT || error "umount failed"
20707         mount_client $MOUNT || error "mount failed"
20708         stop ost1 || error "cannot stop ost1"
20709         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20710 }
20711 run_test 232a "failed lock should not block umount"
20712
20713 test_232b() {
20714         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20715                 skip "Need MDS version at least 2.10.58"
20716
20717         mkdir -p $DIR/$tdir
20718         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20720         sync
20721         cancel_lru_locks osc
20722
20723         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20724         do_facet ost1 $LCTL set_param fail_loc=0x31c
20725
20726         # ignore failure
20727         $LFS data_version $DIR/$tdir/$tfile || true
20728
20729         do_facet ost1 $LCTL set_param fail_loc=0
20730         umount_client $MOUNT || error "umount failed"
20731         mount_client $MOUNT || error "mount failed"
20732         stop ost1 || error "cannot stop ost1"
20733         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20734 }
20735 run_test 232b "failed data version lock should not block umount"
20736
20737 test_233a() {
20738         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20739                 skip "Need MDS version at least 2.3.64"
20740         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20741
20742         local fid=$($LFS path2fid $MOUNT)
20743
20744         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20745                 error "cannot access $MOUNT using its FID '$fid'"
20746 }
20747 run_test 233a "checking that OBF of the FS root succeeds"
20748
20749 test_233b() {
20750         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20751                 skip "Need MDS version at least 2.5.90"
20752         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20753
20754         local fid=$($LFS path2fid $MOUNT/.lustre)
20755
20756         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20757                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20758
20759         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20760         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20761                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20762 }
20763 run_test 233b "checking that OBF of the FS .lustre succeeds"
20764
20765 test_234() {
20766         local p="$TMP/sanityN-$TESTNAME.parameters"
20767         save_lustre_params client "llite.*.xattr_cache" > $p
20768         lctl set_param llite.*.xattr_cache 1 ||
20769                 skip_env "xattr cache is not supported"
20770
20771         mkdir -p $DIR/$tdir || error "mkdir failed"
20772         touch $DIR/$tdir/$tfile || error "touch failed"
20773         # OBD_FAIL_LLITE_XATTR_ENOMEM
20774         $LCTL set_param fail_loc=0x1405
20775         getfattr -n user.attr $DIR/$tdir/$tfile &&
20776                 error "getfattr should have failed with ENOMEM"
20777         $LCTL set_param fail_loc=0x0
20778         rm -rf $DIR/$tdir
20779
20780         restore_lustre_params < $p
20781         rm -f $p
20782 }
20783 run_test 234 "xattr cache should not crash on ENOMEM"
20784
20785 test_235() {
20786         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20787                 skip "Need MDS version at least 2.4.52"
20788
20789         flock_deadlock $DIR/$tfile
20790         local RC=$?
20791         case $RC in
20792                 0)
20793                 ;;
20794                 124) error "process hangs on a deadlock"
20795                 ;;
20796                 *) error "error executing flock_deadlock $DIR/$tfile"
20797                 ;;
20798         esac
20799 }
20800 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20801
20802 #LU-2935
20803 test_236() {
20804         check_swap_layouts_support
20805
20806         local ref1=/etc/passwd
20807         local ref2=/etc/group
20808         local file1=$DIR/$tdir/f1
20809         local file2=$DIR/$tdir/f2
20810
20811         test_mkdir -c1 $DIR/$tdir
20812         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20813         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20814         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20815         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20816         local fd=$(free_fd)
20817         local cmd="exec $fd<>$file2"
20818         eval $cmd
20819         rm $file2
20820         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20821                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20822         cmd="exec $fd>&-"
20823         eval $cmd
20824         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20825
20826         #cleanup
20827         rm -rf $DIR/$tdir
20828 }
20829 run_test 236 "Layout swap on open unlinked file"
20830
20831 # LU-4659 linkea consistency
20832 test_238() {
20833         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20834                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20835                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20836                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20837
20838         touch $DIR/$tfile
20839         ln $DIR/$tfile $DIR/$tfile.lnk
20840         touch $DIR/$tfile.new
20841         mv $DIR/$tfile.new $DIR/$tfile
20842         local fid1=$($LFS path2fid $DIR/$tfile)
20843         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20844         local path1=$($LFS fid2path $FSNAME "$fid1")
20845         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20846         local path2=$($LFS fid2path $FSNAME "$fid2")
20847         [ $tfile.lnk == $path2 ] ||
20848                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20849         rm -f $DIR/$tfile*
20850 }
20851 run_test 238 "Verify linkea consistency"
20852
20853 test_239A() { # was test_239
20854         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20855                 skip "Need MDS version at least 2.5.60"
20856
20857         local list=$(comma_list $(mdts_nodes))
20858
20859         mkdir -p $DIR/$tdir
20860         createmany -o $DIR/$tdir/f- 5000
20861         unlinkmany $DIR/$tdir/f- 5000
20862         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20863                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20864         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20865                         osp.*MDT*.sync_in_flight" | calc_sum)
20866         [ "$changes" -eq 0 ] || error "$changes not synced"
20867 }
20868 run_test 239A "osp_sync test"
20869
20870 test_239a() { #LU-5297
20871         remote_mds_nodsh && skip "remote MDS with nodsh"
20872
20873         touch $DIR/$tfile
20874         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20875         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20876         chgrp $RUNAS_GID $DIR/$tfile
20877         wait_delete_completed
20878 }
20879 run_test 239a "process invalid osp sync record correctly"
20880
20881 test_239b() { #LU-5297
20882         remote_mds_nodsh && skip "remote MDS with nodsh"
20883
20884         touch $DIR/$tfile1
20885         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20886         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20887         chgrp $RUNAS_GID $DIR/$tfile1
20888         wait_delete_completed
20889         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20890         touch $DIR/$tfile2
20891         chgrp $RUNAS_GID $DIR/$tfile2
20892         wait_delete_completed
20893 }
20894 run_test 239b "process osp sync record with ENOMEM error correctly"
20895
20896 test_240() {
20897         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20898         remote_mds_nodsh && skip "remote MDS with nodsh"
20899
20900         mkdir -p $DIR/$tdir
20901
20902         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20903                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20904         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20905                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20906
20907         umount_client $MOUNT || error "umount failed"
20908         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20909         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20910         mount_client $MOUNT || error "failed to mount client"
20911
20912         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20913         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20914 }
20915 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20916
20917 test_241_bio() {
20918         local count=$1
20919         local bsize=$2
20920
20921         for LOOP in $(seq $count); do
20922                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20923                 cancel_lru_locks $OSC || true
20924         done
20925 }
20926
20927 test_241_dio() {
20928         local count=$1
20929         local bsize=$2
20930
20931         for LOOP in $(seq $1); do
20932                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20933                         2>/dev/null
20934         done
20935 }
20936
20937 test_241a() { # was test_241
20938         local bsize=$PAGE_SIZE
20939
20940         (( bsize < 40960 )) && bsize=40960
20941         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20942         ls -la $DIR/$tfile
20943         cancel_lru_locks $OSC
20944         test_241_bio 1000 $bsize &
20945         PID=$!
20946         test_241_dio 1000 $bsize
20947         wait $PID
20948 }
20949 run_test 241a "bio vs dio"
20950
20951 test_241b() {
20952         local bsize=$PAGE_SIZE
20953
20954         (( bsize < 40960 )) && bsize=40960
20955         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20956         ls -la $DIR/$tfile
20957         test_241_dio 1000 $bsize &
20958         PID=$!
20959         test_241_dio 1000 $bsize
20960         wait $PID
20961 }
20962 run_test 241b "dio vs dio"
20963
20964 test_242() {
20965         remote_mds_nodsh && skip "remote MDS with nodsh"
20966
20967         mkdir_on_mdt0 $DIR/$tdir
20968         touch $DIR/$tdir/$tfile
20969
20970         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20971         do_facet mds1 lctl set_param fail_loc=0x105
20972         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20973
20974         do_facet mds1 lctl set_param fail_loc=0
20975         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20976 }
20977 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20978
20979 test_243()
20980 {
20981         test_mkdir $DIR/$tdir
20982         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20983 }
20984 run_test 243 "various group lock tests"
20985
20986 test_244a()
20987 {
20988         test_mkdir $DIR/$tdir
20989         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20990         sendfile_grouplock $DIR/$tdir/$tfile || \
20991                 error "sendfile+grouplock failed"
20992         rm -rf $DIR/$tdir
20993 }
20994 run_test 244a "sendfile with group lock tests"
20995
20996 test_244b()
20997 {
20998         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20999
21000         local threads=50
21001         local size=$((1024*1024))
21002
21003         test_mkdir $DIR/$tdir
21004         for i in $(seq 1 $threads); do
21005                 local file=$DIR/$tdir/file_$((i / 10))
21006                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21007                 local pids[$i]=$!
21008         done
21009         for i in $(seq 1 $threads); do
21010                 wait ${pids[$i]}
21011         done
21012 }
21013 run_test 244b "multi-threaded write with group lock"
21014
21015 test_245a() {
21016         local flagname="multi_mod_rpcs"
21017         local connect_data_name="max_mod_rpcs"
21018         local out
21019
21020         # check if multiple modify RPCs flag is set
21021         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21022                 grep "connect_flags:")
21023         echo "$out"
21024
21025         echo "$out" | grep -qw $flagname
21026         if [ $? -ne 0 ]; then
21027                 echo "connect flag $flagname is not set"
21028                 return
21029         fi
21030
21031         # check if multiple modify RPCs data is set
21032         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21033         echo "$out"
21034
21035         echo "$out" | grep -qw $connect_data_name ||
21036                 error "import should have connect data $connect_data_name"
21037 }
21038 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21039
21040 test_245b() {
21041         local flagname="multi_mod_rpcs"
21042         local connect_data_name="max_mod_rpcs"
21043         local out
21044
21045         remote_mds_nodsh && skip "remote MDS with nodsh"
21046         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21047
21048         # check if multiple modify RPCs flag is set
21049         out=$(do_facet mds1 \
21050               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21051               grep "connect_flags:")
21052         echo "$out"
21053
21054         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21055
21056         # check if multiple modify RPCs data is set
21057         out=$(do_facet mds1 \
21058               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21059
21060         [[ "$out" =~ $connect_data_name ]] ||
21061                 {
21062                         echo "$out"
21063                         error "missing connect data $connect_data_name"
21064                 }
21065 }
21066 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21067
21068 cleanup_247() {
21069         local submount=$1
21070
21071         trap 0
21072         umount_client $submount
21073         rmdir $submount
21074 }
21075
21076 test_247a() {
21077         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21078                 grep -q subtree ||
21079                 skip_env "Fileset feature is not supported"
21080
21081         local submount=${MOUNT}_$tdir
21082
21083         mkdir $MOUNT/$tdir
21084         mkdir -p $submount || error "mkdir $submount failed"
21085         FILESET="$FILESET/$tdir" mount_client $submount ||
21086                 error "mount $submount failed"
21087         trap "cleanup_247 $submount" EXIT
21088         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21089         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21090                 error "read $MOUNT/$tdir/$tfile failed"
21091         cleanup_247 $submount
21092 }
21093 run_test 247a "mount subdir as fileset"
21094
21095 test_247b() {
21096         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21097                 skip_env "Fileset feature is not supported"
21098
21099         local submount=${MOUNT}_$tdir
21100
21101         rm -rf $MOUNT/$tdir
21102         mkdir -p $submount || error "mkdir $submount failed"
21103         SKIP_FILESET=1
21104         FILESET="$FILESET/$tdir" mount_client $submount &&
21105                 error "mount $submount should fail"
21106         rmdir $submount
21107 }
21108 run_test 247b "mount subdir that dose not exist"
21109
21110 test_247c() {
21111         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21112                 skip_env "Fileset feature is not supported"
21113
21114         local submount=${MOUNT}_$tdir
21115
21116         mkdir -p $MOUNT/$tdir/dir1
21117         mkdir -p $submount || error "mkdir $submount failed"
21118         trap "cleanup_247 $submount" EXIT
21119         FILESET="$FILESET/$tdir" mount_client $submount ||
21120                 error "mount $submount failed"
21121         local fid=$($LFS path2fid $MOUNT/)
21122         $LFS fid2path $submount $fid && error "fid2path should fail"
21123         cleanup_247 $submount
21124 }
21125 run_test 247c "running fid2path outside subdirectory root"
21126
21127 test_247d() {
21128         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21129                 skip "Fileset feature is not supported"
21130
21131         local submount=${MOUNT}_$tdir
21132
21133         mkdir -p $MOUNT/$tdir/dir1
21134         mkdir -p $submount || error "mkdir $submount failed"
21135         FILESET="$FILESET/$tdir" mount_client $submount ||
21136                 error "mount $submount failed"
21137         trap "cleanup_247 $submount" EXIT
21138
21139         local td=$submount/dir1
21140         local fid=$($LFS path2fid $td)
21141         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21142
21143         # check that we get the same pathname back
21144         local rootpath
21145         local found
21146         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21147                 echo "$rootpath $fid"
21148                 found=$($LFS fid2path $rootpath "$fid")
21149                 [ -n "$found" ] || error "fid2path should succeed"
21150                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21151         done
21152         # check wrong root path format
21153         rootpath=$submount"_wrong"
21154         found=$($LFS fid2path $rootpath "$fid")
21155         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21156
21157         cleanup_247 $submount
21158 }
21159 run_test 247d "running fid2path inside subdirectory root"
21160
21161 # LU-8037
21162 test_247e() {
21163         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21164                 grep -q subtree ||
21165                 skip "Fileset feature is not supported"
21166
21167         local submount=${MOUNT}_$tdir
21168
21169         mkdir $MOUNT/$tdir
21170         mkdir -p $submount || error "mkdir $submount failed"
21171         FILESET="$FILESET/.." mount_client $submount &&
21172                 error "mount $submount should fail"
21173         rmdir $submount
21174 }
21175 run_test 247e "mount .. as fileset"
21176
21177 test_247f() {
21178         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21179         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21180                 skip "Need at least version 2.13.52"
21181         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21182                 skip "Need at least version 2.14.50"
21183         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21184                 grep -q subtree ||
21185                 skip "Fileset feature is not supported"
21186
21187         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21188         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21189                 error "mkdir remote failed"
21190         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21191                 error "mkdir remote/subdir failed"
21192         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21193                 error "mkdir striped failed"
21194         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21195
21196         local submount=${MOUNT}_$tdir
21197
21198         mkdir -p $submount || error "mkdir $submount failed"
21199         stack_trap "rmdir $submount"
21200
21201         local dir
21202         local stat
21203         local fileset=$FILESET
21204         local mdts=$(comma_list $(mdts_nodes))
21205
21206         stat=$(do_facet mds1 $LCTL get_param -n \
21207                 mdt.*MDT0000.enable_remote_subdir_mount)
21208         stack_trap "do_nodes $mdts $LCTL set_param \
21209                 mdt.*.enable_remote_subdir_mount=$stat"
21210
21211         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21212         stack_trap "umount_client $submount"
21213         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21214                 error "mount remote dir $dir should fail"
21215
21216         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21217                 $tdir/striped/. ; do
21218                 FILESET="$fileset/$dir" mount_client $submount ||
21219                         error "mount $dir failed"
21220                 umount_client $submount
21221         done
21222
21223         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21224         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21225                 error "mount $tdir/remote failed"
21226 }
21227 run_test 247f "mount striped or remote directory as fileset"
21228
21229 test_247g() {
21230         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21231         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21232                 skip "Need at least version 2.14.50"
21233
21234         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21235                 error "mkdir $tdir failed"
21236         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21237
21238         local submount=${MOUNT}_$tdir
21239
21240         mkdir -p $submount || error "mkdir $submount failed"
21241         stack_trap "rmdir $submount"
21242
21243         FILESET="$fileset/$tdir" mount_client $submount ||
21244                 error "mount $dir failed"
21245         stack_trap "umount $submount"
21246
21247         local mdts=$(comma_list $(mdts_nodes))
21248
21249         local nrpcs
21250
21251         stat $submount > /dev/null
21252         cancel_lru_locks $MDC
21253         stat $submount > /dev/null
21254         stat $submount/$tfile > /dev/null
21255         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21256         stat $submount/$tfile > /dev/null
21257         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21258                 awk '/getattr/ {sum += $2} END {print sum}')
21259
21260         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21261 }
21262 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21263
21264 test_248a() {
21265         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21266         [ -z "$fast_read_sav" ] && skip "no fast read support"
21267
21268         # create a large file for fast read verification
21269         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21270
21271         # make sure the file is created correctly
21272         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21273                 { rm -f $DIR/$tfile; skip "file creation error"; }
21274
21275         echo "Test 1: verify that fast read is 4 times faster on cache read"
21276
21277         # small read with fast read enabled
21278         $LCTL set_param -n llite.*.fast_read=1
21279         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21280                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21281                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21282         # small read with fast read disabled
21283         $LCTL set_param -n llite.*.fast_read=0
21284         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21285                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21286                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21287
21288         # verify that fast read is 4 times faster for cache read
21289         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21290                 error_not_in_vm "fast read was not 4 times faster: " \
21291                            "$t_fast vs $t_slow"
21292
21293         echo "Test 2: verify the performance between big and small read"
21294         $LCTL set_param -n llite.*.fast_read=1
21295
21296         # 1k non-cache read
21297         cancel_lru_locks osc
21298         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21299                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21300                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21301
21302         # 1M non-cache read
21303         cancel_lru_locks osc
21304         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21305                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21306                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21307
21308         # verify that big IO is not 4 times faster than small IO
21309         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21310                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21311
21312         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21313         rm -f $DIR/$tfile
21314 }
21315 run_test 248a "fast read verification"
21316
21317 test_248b() {
21318         # Default short_io_bytes=16384, try both smaller and larger sizes.
21319         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21320         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21321         echo "bs=53248 count=113 normal buffered write"
21322         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21323                 error "dd of initial data file failed"
21324         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21325
21326         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21327         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21328                 error "dd with sync normal writes failed"
21329         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21330
21331         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21332         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21333                 error "dd with sync small writes failed"
21334         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21335
21336         cancel_lru_locks osc
21337
21338         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21339         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21340         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21341         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21342                 iflag=direct || error "dd with O_DIRECT small read failed"
21343         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21344         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21345                 error "compare $TMP/$tfile.1 failed"
21346
21347         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21348         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21349
21350         # just to see what the maximum tunable value is, and test parsing
21351         echo "test invalid parameter 2MB"
21352         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21353                 error "too-large short_io_bytes allowed"
21354         echo "test maximum parameter 512KB"
21355         # if we can set a larger short_io_bytes, run test regardless of version
21356         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21357                 # older clients may not allow setting it this large, that's OK
21358                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21359                         skip "Need at least client version 2.13.50"
21360                 error "medium short_io_bytes failed"
21361         fi
21362         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21363         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21364
21365         echo "test large parameter 64KB"
21366         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21367         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21368
21369         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21370         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21371                 error "dd with sync large writes failed"
21372         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21373
21374         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21375         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21376         num=$((113 * 4096 / PAGE_SIZE))
21377         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21378         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21379                 error "dd with O_DIRECT large writes failed"
21380         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21381                 error "compare $DIR/$tfile.3 failed"
21382
21383         cancel_lru_locks osc
21384
21385         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21386         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21387                 error "dd with O_DIRECT large read failed"
21388         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21389                 error "compare $TMP/$tfile.2 failed"
21390
21391         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21392         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21393                 error "dd with O_DIRECT large read failed"
21394         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21395                 error "compare $TMP/$tfile.3 failed"
21396 }
21397 run_test 248b "test short_io read and write for both small and large sizes"
21398
21399 test_249() { # LU-7890
21400         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21401                 skip "Need at least version 2.8.54"
21402
21403         rm -f $DIR/$tfile
21404         $LFS setstripe -c 1 $DIR/$tfile
21405         # Offset 2T == 4k * 512M
21406         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21407                 error "dd to 2T offset failed"
21408 }
21409 run_test 249 "Write above 2T file size"
21410
21411 test_250() {
21412         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21413          && skip "no 16TB file size limit on ZFS"
21414
21415         $LFS setstripe -c 1 $DIR/$tfile
21416         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21417         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21418         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21419         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21420                 conv=notrunc,fsync && error "append succeeded"
21421         return 0
21422 }
21423 run_test 250 "Write above 16T limit"
21424
21425 test_251() {
21426         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21427
21428         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21429         #Skip once - writing the first stripe will succeed
21430         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21431         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21432                 error "short write happened"
21433
21434         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21435         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21436                 error "short read happened"
21437
21438         rm -f $DIR/$tfile
21439 }
21440 run_test 251 "Handling short read and write correctly"
21441
21442 test_252() {
21443         remote_mds_nodsh && skip "remote MDS with nodsh"
21444         remote_ost_nodsh && skip "remote OST with nodsh"
21445         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21446                 skip_env "ldiskfs only test"
21447         fi
21448
21449         local tgt
21450         local dev
21451         local out
21452         local uuid
21453         local num
21454         local gen
21455
21456         # check lr_reader on OST0000
21457         tgt=ost1
21458         dev=$(facet_device $tgt)
21459         out=$(do_facet $tgt $LR_READER $dev)
21460         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21461         echo "$out"
21462         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21463         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21464                 error "Invalid uuid returned by $LR_READER on target $tgt"
21465         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21466
21467         # check lr_reader -c on MDT0000
21468         tgt=mds1
21469         dev=$(facet_device $tgt)
21470         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21471                 skip "$LR_READER does not support additional options"
21472         fi
21473         out=$(do_facet $tgt $LR_READER -c $dev)
21474         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21475         echo "$out"
21476         num=$(echo "$out" | grep -c "mdtlov")
21477         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21478                 error "Invalid number of mdtlov clients returned by $LR_READER"
21479         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21480
21481         # check lr_reader -cr on MDT0000
21482         out=$(do_facet $tgt $LR_READER -cr $dev)
21483         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21484         echo "$out"
21485         echo "$out" | grep -q "^reply_data:$" ||
21486                 error "$LR_READER should have returned 'reply_data' section"
21487         num=$(echo "$out" | grep -c "client_generation")
21488         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21489 }
21490 run_test 252 "check lr_reader tool"
21491
21492 test_253() {
21493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21494         remote_mds_nodsh && skip "remote MDS with nodsh"
21495         remote_mgs_nodsh && skip "remote MGS with nodsh"
21496
21497         local ostidx=0
21498         local rc=0
21499         local ost_name=$(ostname_from_index $ostidx)
21500
21501         # on the mdt's osc
21502         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21503         do_facet $SINGLEMDS $LCTL get_param -n \
21504                 osp.$mdtosc_proc1.reserved_mb_high ||
21505                 skip  "remote MDS does not support reserved_mb_high"
21506
21507         rm -rf $DIR/$tdir
21508         wait_mds_ost_sync
21509         wait_delete_completed
21510         mkdir $DIR/$tdir
21511
21512         pool_add $TESTNAME || error "Pool creation failed"
21513         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21514
21515         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21516                 error "Setstripe failed"
21517
21518         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21519
21520         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21521                     grep "watermarks")
21522         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21523
21524         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21525                         osp.$mdtosc_proc1.prealloc_status)
21526         echo "prealloc_status $oa_status"
21527
21528         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21529                 error "File creation should fail"
21530
21531         #object allocation was stopped, but we still able to append files
21532         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21533                 oflag=append || error "Append failed"
21534
21535         rm -f $DIR/$tdir/$tfile.0
21536
21537         # For this test, we want to delete the files we created to go out of
21538         # space but leave the watermark, so we remain nearly out of space
21539         ost_watermarks_enospc_delete_files $tfile $ostidx
21540
21541         wait_delete_completed
21542
21543         sleep_maxage
21544
21545         for i in $(seq 10 12); do
21546                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21547                         2>/dev/null || error "File creation failed after rm"
21548         done
21549
21550         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21551                         osp.$mdtosc_proc1.prealloc_status)
21552         echo "prealloc_status $oa_status"
21553
21554         if (( oa_status != 0 )); then
21555                 error "Object allocation still disable after rm"
21556         fi
21557 }
21558 run_test 253 "Check object allocation limit"
21559
21560 test_254() {
21561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21562         remote_mds_nodsh && skip "remote MDS with nodsh"
21563
21564         local mdt=$(facet_svc $SINGLEMDS)
21565
21566         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21567                 skip "MDS does not support changelog_size"
21568
21569         local cl_user
21570
21571         changelog_register || error "changelog_register failed"
21572
21573         changelog_clear 0 || error "changelog_clear failed"
21574
21575         local size1=$(do_facet $SINGLEMDS \
21576                       $LCTL get_param -n mdd.$mdt.changelog_size)
21577         echo "Changelog size $size1"
21578
21579         rm -rf $DIR/$tdir
21580         $LFS mkdir -i 0 $DIR/$tdir
21581         # change something
21582         mkdir -p $DIR/$tdir/pics/2008/zachy
21583         touch $DIR/$tdir/pics/2008/zachy/timestamp
21584         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21585         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21586         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21587         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21588         rm $DIR/$tdir/pics/desktop.jpg
21589
21590         local size2=$(do_facet $SINGLEMDS \
21591                       $LCTL get_param -n mdd.$mdt.changelog_size)
21592         echo "Changelog size after work $size2"
21593
21594         (( $size2 > $size1 )) ||
21595                 error "new Changelog size=$size2 less than old size=$size1"
21596 }
21597 run_test 254 "Check changelog size"
21598
21599 ladvise_no_type()
21600 {
21601         local type=$1
21602         local file=$2
21603
21604         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21605                 awk -F: '{print $2}' | grep $type > /dev/null
21606         if [ $? -ne 0 ]; then
21607                 return 0
21608         fi
21609         return 1
21610 }
21611
21612 ladvise_no_ioctl()
21613 {
21614         local file=$1
21615
21616         lfs ladvise -a willread $file > /dev/null 2>&1
21617         if [ $? -eq 0 ]; then
21618                 return 1
21619         fi
21620
21621         lfs ladvise -a willread $file 2>&1 |
21622                 grep "Inappropriate ioctl for device" > /dev/null
21623         if [ $? -eq 0 ]; then
21624                 return 0
21625         fi
21626         return 1
21627 }
21628
21629 percent() {
21630         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21631 }
21632
21633 # run a random read IO workload
21634 # usage: random_read_iops <filename> <filesize> <iosize>
21635 random_read_iops() {
21636         local file=$1
21637         local fsize=$2
21638         local iosize=${3:-4096}
21639
21640         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21641                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21642 }
21643
21644 drop_file_oss_cache() {
21645         local file="$1"
21646         local nodes="$2"
21647
21648         $LFS ladvise -a dontneed $file 2>/dev/null ||
21649                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21650 }
21651
21652 ladvise_willread_performance()
21653 {
21654         local repeat=10
21655         local average_origin=0
21656         local average_cache=0
21657         local average_ladvise=0
21658
21659         for ((i = 1; i <= $repeat; i++)); do
21660                 echo "Iter $i/$repeat: reading without willread hint"
21661                 cancel_lru_locks osc
21662                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21663                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21664                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21665                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21666
21667                 cancel_lru_locks osc
21668                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21669                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21670                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21671
21672                 cancel_lru_locks osc
21673                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21674                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21675                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21676                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21677                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21678         done
21679         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21680         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21681         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21682
21683         speedup_cache=$(percent $average_cache $average_origin)
21684         speedup_ladvise=$(percent $average_ladvise $average_origin)
21685
21686         echo "Average uncached read: $average_origin"
21687         echo "Average speedup with OSS cached read: " \
21688                 "$average_cache = +$speedup_cache%"
21689         echo "Average speedup with ladvise willread: " \
21690                 "$average_ladvise = +$speedup_ladvise%"
21691
21692         local lowest_speedup=20
21693         if (( ${average_cache%.*} < $lowest_speedup )); then
21694                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21695                      " got $average_cache%. Skipping ladvise willread check."
21696                 return 0
21697         fi
21698
21699         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21700         # it is still good to run until then to exercise 'ladvise willread'
21701         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21702                 [ "$ost1_FSTYPE" = "zfs" ] &&
21703                 echo "osd-zfs does not support dontneed or drop_caches" &&
21704                 return 0
21705
21706         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21707         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21708                 error_not_in_vm "Speedup with willread is less than " \
21709                         "$lowest_speedup%, got $average_ladvise%"
21710 }
21711
21712 test_255a() {
21713         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21714                 skip "lustre < 2.8.54 does not support ladvise "
21715         remote_ost_nodsh && skip "remote OST with nodsh"
21716
21717         stack_trap "rm -f $DIR/$tfile"
21718         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21719
21720         ladvise_no_type willread $DIR/$tfile &&
21721                 skip "willread ladvise is not supported"
21722
21723         ladvise_no_ioctl $DIR/$tfile &&
21724                 skip "ladvise ioctl is not supported"
21725
21726         local size_mb=100
21727         local size=$((size_mb * 1048576))
21728         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21729                 error "dd to $DIR/$tfile failed"
21730
21731         lfs ladvise -a willread $DIR/$tfile ||
21732                 error "Ladvise failed with no range argument"
21733
21734         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21735                 error "Ladvise failed with no -l or -e argument"
21736
21737         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21738                 error "Ladvise failed with only -e argument"
21739
21740         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21741                 error "Ladvise failed with only -l argument"
21742
21743         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21744                 error "End offset should not be smaller than start offset"
21745
21746         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21747                 error "End offset should not be equal to start offset"
21748
21749         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21750                 error "Ladvise failed with overflowing -s argument"
21751
21752         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21753                 error "Ladvise failed with overflowing -e argument"
21754
21755         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21756                 error "Ladvise failed with overflowing -l argument"
21757
21758         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21759                 error "Ladvise succeeded with conflicting -l and -e arguments"
21760
21761         echo "Synchronous ladvise should wait"
21762         local delay=4
21763 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21764         do_nodes $(comma_list $(osts_nodes)) \
21765                 $LCTL set_param fail_val=$delay fail_loc=0x237
21766
21767         local start_ts=$SECONDS
21768         lfs ladvise -a willread $DIR/$tfile ||
21769                 error "Ladvise failed with no range argument"
21770         local end_ts=$SECONDS
21771         local inteval_ts=$((end_ts - start_ts))
21772
21773         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21774                 error "Synchronous advice didn't wait reply"
21775         fi
21776
21777         echo "Asynchronous ladvise shouldn't wait"
21778         local start_ts=$SECONDS
21779         lfs ladvise -a willread -b $DIR/$tfile ||
21780                 error "Ladvise failed with no range argument"
21781         local end_ts=$SECONDS
21782         local inteval_ts=$((end_ts - start_ts))
21783
21784         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21785                 error "Asynchronous advice blocked"
21786         fi
21787
21788         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21789         ladvise_willread_performance
21790 }
21791 run_test 255a "check 'lfs ladvise -a willread'"
21792
21793 facet_meminfo() {
21794         local facet=$1
21795         local info=$2
21796
21797         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21798 }
21799
21800 test_255b() {
21801         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21802                 skip "lustre < 2.8.54 does not support ladvise "
21803         remote_ost_nodsh && skip "remote OST with nodsh"
21804
21805         stack_trap "rm -f $DIR/$tfile"
21806         lfs setstripe -c 1 -i 0 $DIR/$tfile
21807
21808         ladvise_no_type dontneed $DIR/$tfile &&
21809                 skip "dontneed ladvise is not supported"
21810
21811         ladvise_no_ioctl $DIR/$tfile &&
21812                 skip "ladvise ioctl is not supported"
21813
21814         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21815                 [ "$ost1_FSTYPE" = "zfs" ] &&
21816                 skip "zfs-osd does not support 'ladvise dontneed'"
21817
21818         local size_mb=100
21819         local size=$((size_mb * 1048576))
21820         # In order to prevent disturbance of other processes, only check 3/4
21821         # of the memory usage
21822         local kibibytes=$((size_mb * 1024 * 3 / 4))
21823
21824         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21825                 error "dd to $DIR/$tfile failed"
21826
21827         #force write to complete before dropping OST cache & checking memory
21828         sync
21829
21830         local total=$(facet_meminfo ost1 MemTotal)
21831         echo "Total memory: $total KiB"
21832
21833         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21834         local before_read=$(facet_meminfo ost1 Cached)
21835         echo "Cache used before read: $before_read KiB"
21836
21837         lfs ladvise -a willread $DIR/$tfile ||
21838                 error "Ladvise willread failed"
21839         local after_read=$(facet_meminfo ost1 Cached)
21840         echo "Cache used after read: $after_read KiB"
21841
21842         lfs ladvise -a dontneed $DIR/$tfile ||
21843                 error "Ladvise dontneed again failed"
21844         local no_read=$(facet_meminfo ost1 Cached)
21845         echo "Cache used after dontneed ladvise: $no_read KiB"
21846
21847         if [ $total -lt $((before_read + kibibytes)) ]; then
21848                 echo "Memory is too small, abort checking"
21849                 return 0
21850         fi
21851
21852         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21853                 error "Ladvise willread should use more memory" \
21854                         "than $kibibytes KiB"
21855         fi
21856
21857         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21858                 error "Ladvise dontneed should release more memory" \
21859                         "than $kibibytes KiB"
21860         fi
21861 }
21862 run_test 255b "check 'lfs ladvise -a dontneed'"
21863
21864 test_255c() {
21865         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21866                 skip "lustre < 2.10.50 does not support lockahead"
21867
21868         local ost1_imp=$(get_osc_import_name client ost1)
21869         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21870                          cut -d'.' -f2)
21871         local count
21872         local new_count
21873         local difference
21874         local i
21875         local rc
21876
21877         test_mkdir -p $DIR/$tdir
21878         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21879
21880         #test 10 returns only success/failure
21881         i=10
21882         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21883         rc=$?
21884         if [ $rc -eq 255 ]; then
21885                 error "Ladvise test${i} failed, ${rc}"
21886         fi
21887
21888         #test 11 counts lock enqueue requests, all others count new locks
21889         i=11
21890         count=$(do_facet ost1 \
21891                 $LCTL get_param -n ost.OSS.ost.stats)
21892         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21893
21894         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21895         rc=$?
21896         if [ $rc -eq 255 ]; then
21897                 error "Ladvise test${i} failed, ${rc}"
21898         fi
21899
21900         new_count=$(do_facet ost1 \
21901                 $LCTL get_param -n ost.OSS.ost.stats)
21902         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21903                    awk '{ print $2 }')
21904
21905         difference="$((new_count - count))"
21906         if [ $difference -ne $rc ]; then
21907                 error "Ladvise test${i}, bad enqueue count, returned " \
21908                       "${rc}, actual ${difference}"
21909         fi
21910
21911         for i in $(seq 12 21); do
21912                 # If we do not do this, we run the risk of having too many
21913                 # locks and starting lock cancellation while we are checking
21914                 # lock counts.
21915                 cancel_lru_locks osc
21916
21917                 count=$($LCTL get_param -n \
21918                        ldlm.namespaces.$imp_name.lock_unused_count)
21919
21920                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21921                 rc=$?
21922                 if [ $rc -eq 255 ]; then
21923                         error "Ladvise test ${i} failed, ${rc}"
21924                 fi
21925
21926                 new_count=$($LCTL get_param -n \
21927                        ldlm.namespaces.$imp_name.lock_unused_count)
21928                 difference="$((new_count - count))"
21929
21930                 # Test 15 output is divided by 100 to map down to valid return
21931                 if [ $i -eq 15 ]; then
21932                         rc="$((rc * 100))"
21933                 fi
21934
21935                 if [ $difference -ne $rc ]; then
21936                         error "Ladvise test ${i}, bad lock count, returned " \
21937                               "${rc}, actual ${difference}"
21938                 fi
21939         done
21940
21941         #test 22 returns only success/failure
21942         i=22
21943         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21944         rc=$?
21945         if [ $rc -eq 255 ]; then
21946                 error "Ladvise test${i} failed, ${rc}"
21947         fi
21948 }
21949 run_test 255c "suite of ladvise lockahead tests"
21950
21951 test_256() {
21952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21953         remote_mds_nodsh && skip "remote MDS with nodsh"
21954         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21955         changelog_users $SINGLEMDS | grep "^cl" &&
21956                 skip "active changelog user"
21957
21958         local cl_user
21959         local cat_sl
21960         local mdt_dev
21961
21962         mdt_dev=$(facet_device $SINGLEMDS)
21963         echo $mdt_dev
21964
21965         changelog_register || error "changelog_register failed"
21966
21967         rm -rf $DIR/$tdir
21968         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21969
21970         changelog_clear 0 || error "changelog_clear failed"
21971
21972         # change something
21973         touch $DIR/$tdir/{1..10}
21974
21975         # stop the MDT
21976         stop $SINGLEMDS || error "Fail to stop MDT"
21977
21978         # remount the MDT
21979         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21980                 error "Fail to start MDT"
21981
21982         #after mount new plainllog is used
21983         touch $DIR/$tdir/{11..19}
21984         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21985         stack_trap "rm -f $tmpfile"
21986         cat_sl=$(do_facet $SINGLEMDS "sync; \
21987                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21988                  llog_reader $tmpfile | grep -c type=1064553b")
21989         do_facet $SINGLEMDS llog_reader $tmpfile
21990
21991         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21992
21993         changelog_clear 0 || error "changelog_clear failed"
21994
21995         cat_sl=$(do_facet $SINGLEMDS "sync; \
21996                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21997                  llog_reader $tmpfile | grep -c type=1064553b")
21998
21999         if (( cat_sl == 2 )); then
22000                 error "Empty plain llog was not deleted from changelog catalog"
22001         elif (( cat_sl != 1 )); then
22002                 error "Active plain llog shouldn't be deleted from catalog"
22003         fi
22004 }
22005 run_test 256 "Check llog delete for empty and not full state"
22006
22007 test_257() {
22008         remote_mds_nodsh && skip "remote MDS with nodsh"
22009         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22010                 skip "Need MDS version at least 2.8.55"
22011
22012         test_mkdir $DIR/$tdir
22013
22014         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22015                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22016         stat $DIR/$tdir
22017
22018 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22019         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22020         local facet=mds$((mdtidx + 1))
22021         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22022         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22023
22024         stop $facet || error "stop MDS failed"
22025         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22026                 error "start MDS fail"
22027         wait_recovery_complete $facet
22028 }
22029 run_test 257 "xattr locks are not lost"
22030
22031 # Verify we take the i_mutex when security requires it
22032 test_258a() {
22033 #define OBD_FAIL_IMUTEX_SEC 0x141c
22034         $LCTL set_param fail_loc=0x141c
22035         touch $DIR/$tfile
22036         chmod u+s $DIR/$tfile
22037         chmod a+rwx $DIR/$tfile
22038         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22039         RC=$?
22040         if [ $RC -ne 0 ]; then
22041                 error "error, failed to take i_mutex, rc=$?"
22042         fi
22043         rm -f $DIR/$tfile
22044 }
22045 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22046
22047 # Verify we do NOT take the i_mutex in the normal case
22048 test_258b() {
22049 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22050         $LCTL set_param fail_loc=0x141d
22051         touch $DIR/$tfile
22052         chmod a+rwx $DIR
22053         chmod a+rw $DIR/$tfile
22054         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22055         RC=$?
22056         if [ $RC -ne 0 ]; then
22057                 error "error, took i_mutex unnecessarily, rc=$?"
22058         fi
22059         rm -f $DIR/$tfile
22060
22061 }
22062 run_test 258b "verify i_mutex security behavior"
22063
22064 test_259() {
22065         local file=$DIR/$tfile
22066         local before
22067         local after
22068
22069         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22070
22071         stack_trap "rm -f $file" EXIT
22072
22073         wait_delete_completed
22074         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22075         echo "before: $before"
22076
22077         $LFS setstripe -i 0 -c 1 $file
22078         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22079         sync_all_data
22080         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22081         echo "after write: $after"
22082
22083 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22084         do_facet ost1 $LCTL set_param fail_loc=0x2301
22085         $TRUNCATE $file 0
22086         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22087         echo "after truncate: $after"
22088
22089         stop ost1
22090         do_facet ost1 $LCTL set_param fail_loc=0
22091         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22092         sleep 2
22093         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22094         echo "after restart: $after"
22095         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22096                 error "missing truncate?"
22097
22098         return 0
22099 }
22100 run_test 259 "crash at delayed truncate"
22101
22102 test_260() {
22103 #define OBD_FAIL_MDC_CLOSE               0x806
22104         $LCTL set_param fail_loc=0x80000806
22105         touch $DIR/$tfile
22106
22107 }
22108 run_test 260 "Check mdc_close fail"
22109
22110 ### Data-on-MDT sanity tests ###
22111 test_270a() {
22112         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22113                 skip "Need MDS version at least 2.10.55 for DoM"
22114
22115         # create DoM file
22116         local dom=$DIR/$tdir/dom_file
22117         local tmp=$DIR/$tdir/tmp_file
22118
22119         mkdir_on_mdt0 $DIR/$tdir
22120
22121         # basic checks for DoM component creation
22122         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22123                 error "Can set MDT layout to non-first entry"
22124
22125         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22126                 error "Can define multiple entries as MDT layout"
22127
22128         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22129
22130         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22131         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22132         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22133
22134         local mdtidx=$($LFS getstripe -m $dom)
22135         local mdtname=MDT$(printf %04x $mdtidx)
22136         local facet=mds$((mdtidx + 1))
22137         local space_check=1
22138
22139         # Skip free space checks with ZFS
22140         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22141
22142         # write
22143         sync
22144         local size_tmp=$((65536 * 3))
22145         local mdtfree1=$(do_facet $facet \
22146                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22147
22148         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22149         # check also direct IO along write
22150         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22151         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22152         sync
22153         cmp $tmp $dom || error "file data is different"
22154         [ $(stat -c%s $dom) == $size_tmp ] ||
22155                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22156         if [ $space_check == 1 ]; then
22157                 local mdtfree2=$(do_facet $facet \
22158                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22159
22160                 # increase in usage from by $size_tmp
22161                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22162                         error "MDT free space wrong after write: " \
22163                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22164         fi
22165
22166         # truncate
22167         local size_dom=10000
22168
22169         $TRUNCATE $dom $size_dom
22170         [ $(stat -c%s $dom) == $size_dom ] ||
22171                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22172         if [ $space_check == 1 ]; then
22173                 mdtfree1=$(do_facet $facet \
22174                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22175                 # decrease in usage from $size_tmp to new $size_dom
22176                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22177                   $(((size_tmp - size_dom) / 1024)) ] ||
22178                         error "MDT free space is wrong after truncate: " \
22179                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22180         fi
22181
22182         # append
22183         cat $tmp >> $dom
22184         sync
22185         size_dom=$((size_dom + size_tmp))
22186         [ $(stat -c%s $dom) == $size_dom ] ||
22187                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22188         if [ $space_check == 1 ]; then
22189                 mdtfree2=$(do_facet $facet \
22190                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22191                 # increase in usage by $size_tmp from previous
22192                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22193                         error "MDT free space is wrong after append: " \
22194                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22195         fi
22196
22197         # delete
22198         rm $dom
22199         if [ $space_check == 1 ]; then
22200                 mdtfree1=$(do_facet $facet \
22201                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22202                 # decrease in usage by $size_dom from previous
22203                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22204                         error "MDT free space is wrong after removal: " \
22205                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22206         fi
22207
22208         # combined striping
22209         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22210                 error "Can't create DoM + OST striping"
22211
22212         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22213         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22214         # check also direct IO along write
22215         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22216         sync
22217         cmp $tmp $dom || error "file data is different"
22218         [ $(stat -c%s $dom) == $size_tmp ] ||
22219                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22220         rm $dom $tmp
22221
22222         return 0
22223 }
22224 run_test 270a "DoM: basic functionality tests"
22225
22226 test_270b() {
22227         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22228                 skip "Need MDS version at least 2.10.55"
22229
22230         local dom=$DIR/$tdir/dom_file
22231         local max_size=1048576
22232
22233         mkdir -p $DIR/$tdir
22234         $LFS setstripe -E $max_size -L mdt $dom
22235
22236         # truncate over the limit
22237         $TRUNCATE $dom $(($max_size + 1)) &&
22238                 error "successful truncate over the maximum size"
22239         # write over the limit
22240         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22241                 error "successful write over the maximum size"
22242         # append over the limit
22243         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22244         echo "12345" >> $dom && error "successful append over the maximum size"
22245         rm $dom
22246
22247         return 0
22248 }
22249 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22250
22251 test_270c() {
22252         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22253                 skip "Need MDS version at least 2.10.55"
22254
22255         mkdir -p $DIR/$tdir
22256         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22257
22258         # check files inherit DoM EA
22259         touch $DIR/$tdir/first
22260         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22261                 error "bad pattern"
22262         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22263                 error "bad stripe count"
22264         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22265                 error "bad stripe size"
22266
22267         # check directory inherits DoM EA and uses it as default
22268         mkdir $DIR/$tdir/subdir
22269         touch $DIR/$tdir/subdir/second
22270         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22271                 error "bad pattern in sub-directory"
22272         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22273                 error "bad stripe count in sub-directory"
22274         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22275                 error "bad stripe size in sub-directory"
22276         return 0
22277 }
22278 run_test 270c "DoM: DoM EA inheritance tests"
22279
22280 test_270d() {
22281         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22282                 skip "Need MDS version at least 2.10.55"
22283
22284         mkdir -p $DIR/$tdir
22285         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22286
22287         # inherit default DoM striping
22288         mkdir $DIR/$tdir/subdir
22289         touch $DIR/$tdir/subdir/f1
22290
22291         # change default directory striping
22292         $LFS setstripe -c 1 $DIR/$tdir/subdir
22293         touch $DIR/$tdir/subdir/f2
22294         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22295                 error "wrong default striping in file 2"
22296         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22297                 error "bad pattern in file 2"
22298         return 0
22299 }
22300 run_test 270d "DoM: change striping from DoM to RAID0"
22301
22302 test_270e() {
22303         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22304                 skip "Need MDS version at least 2.10.55"
22305
22306         mkdir -p $DIR/$tdir/dom
22307         mkdir -p $DIR/$tdir/norm
22308         DOMFILES=20
22309         NORMFILES=10
22310         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22311         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22312
22313         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22314         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22315
22316         # find DoM files by layout
22317         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22318         [ $NUM -eq  $DOMFILES ] ||
22319                 error "lfs find -L: found $NUM, expected $DOMFILES"
22320         echo "Test 1: lfs find 20 DOM files by layout: OK"
22321
22322         # there should be 1 dir with default DOM striping
22323         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22324         [ $NUM -eq  1 ] ||
22325                 error "lfs find -L: found $NUM, expected 1 dir"
22326         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22327
22328         # find DoM files by stripe size
22329         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22330         [ $NUM -eq  $DOMFILES ] ||
22331                 error "lfs find -S: found $NUM, expected $DOMFILES"
22332         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22333
22334         # find files by stripe offset except DoM files
22335         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22336         [ $NUM -eq  $NORMFILES ] ||
22337                 error "lfs find -i: found $NUM, expected $NORMFILES"
22338         echo "Test 5: lfs find no DOM files by stripe index: OK"
22339         return 0
22340 }
22341 run_test 270e "DoM: lfs find with DoM files test"
22342
22343 test_270f() {
22344         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22345                 skip "Need MDS version at least 2.10.55"
22346
22347         local mdtname=${FSNAME}-MDT0000-mdtlov
22348         local dom=$DIR/$tdir/dom_file
22349         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22350                                                 lod.$mdtname.dom_stripesize)
22351         local dom_limit=131072
22352
22353         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22354         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22355                                                 lod.$mdtname.dom_stripesize)
22356         [ ${dom_limit} -eq ${dom_current} ] ||
22357                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22358
22359         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22360         $LFS setstripe -d $DIR/$tdir
22361         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22362                 error "Can't set directory default striping"
22363
22364         # exceed maximum stripe size
22365         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22366                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22367         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22368                 error "Able to create DoM component size more than LOD limit"
22369
22370         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22371         dom_current=$(do_facet mds1 $LCTL get_param -n \
22372                                                 lod.$mdtname.dom_stripesize)
22373         [ 0 -eq ${dom_current} ] ||
22374                 error "Can't set zero DoM stripe limit"
22375         rm $dom
22376
22377         # attempt to create DoM file on server with disabled DoM should
22378         # remove DoM entry from layout and be succeed
22379         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22380                 error "Can't create DoM file (DoM is disabled)"
22381         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22382                 error "File has DoM component while DoM is disabled"
22383         rm $dom
22384
22385         # attempt to create DoM file with only DoM stripe should return error
22386         $LFS setstripe -E $dom_limit -L mdt $dom &&
22387                 error "Able to create DoM-only file while DoM is disabled"
22388
22389         # too low values to be aligned with smallest stripe size 64K
22390         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22391         dom_current=$(do_facet mds1 $LCTL get_param -n \
22392                                                 lod.$mdtname.dom_stripesize)
22393         [ 30000 -eq ${dom_current} ] &&
22394                 error "Can set too small DoM stripe limit"
22395
22396         # 64K is a minimal stripe size in Lustre, expect limit of that size
22397         [ 65536 -eq ${dom_current} ] ||
22398                 error "Limit is not set to 64K but ${dom_current}"
22399
22400         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22401         dom_current=$(do_facet mds1 $LCTL get_param -n \
22402                                                 lod.$mdtname.dom_stripesize)
22403         echo $dom_current
22404         [ 2147483648 -eq ${dom_current} ] &&
22405                 error "Can set too large DoM stripe limit"
22406
22407         do_facet mds1 $LCTL set_param -n \
22408                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22409         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22410                 error "Can't create DoM component size after limit change"
22411         do_facet mds1 $LCTL set_param -n \
22412                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22413         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22414                 error "Can't create DoM file after limit decrease"
22415         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22416                 error "Can create big DoM component after limit decrease"
22417         touch ${dom}_def ||
22418                 error "Can't create file with old default layout"
22419
22420         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22421         return 0
22422 }
22423 run_test 270f "DoM: maximum DoM stripe size checks"
22424
22425 test_270g() {
22426         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22427                 skip "Need MDS version at least 2.13.52"
22428         local dom=$DIR/$tdir/$tfile
22429
22430         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22431         local lodname=${FSNAME}-MDT0000-mdtlov
22432
22433         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22434         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22435         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22436         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22437
22438         local dom_limit=1024
22439         local dom_threshold="50%"
22440
22441         $LFS setstripe -d $DIR/$tdir
22442         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22443                 error "Can't set directory default striping"
22444
22445         do_facet mds1 $LCTL set_param -n \
22446                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22447         # set 0 threshold and create DOM file to change tunable stripesize
22448         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22449         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22450                 error "Failed to create $dom file"
22451         # now tunable dom_cur_stripesize should reach maximum
22452         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22453                                         lod.${lodname}.dom_stripesize_cur_kb)
22454         [[ $dom_current == $dom_limit ]] ||
22455                 error "Current DOM stripesize is not maximum"
22456         rm $dom
22457
22458         # set threshold for further tests
22459         do_facet mds1 $LCTL set_param -n \
22460                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22461         echo "DOM threshold is $dom_threshold free space"
22462         local dom_def
22463         local dom_set
22464         # Spoof bfree to exceed threshold
22465         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22466         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22467         for spfree in 40 20 0 15 30 55; do
22468                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22469                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22470                         error "Failed to create $dom file"
22471                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22472                                         lod.${lodname}.dom_stripesize_cur_kb)
22473                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22474                 [[ $dom_def != $dom_current ]] ||
22475                         error "Default stripe size was not changed"
22476                 if (( spfree > 0 )) ; then
22477                         dom_set=$($LFS getstripe -S $dom)
22478                         (( dom_set == dom_def * 1024 )) ||
22479                                 error "DOM component size is still old"
22480                 else
22481                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22482                                 error "DoM component is set with no free space"
22483                 fi
22484                 rm $dom
22485                 dom_current=$dom_def
22486         done
22487 }
22488 run_test 270g "DoM: default DoM stripe size depends on free space"
22489
22490 test_270h() {
22491         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22492                 skip "Need MDS version at least 2.13.53"
22493
22494         local mdtname=${FSNAME}-MDT0000-mdtlov
22495         local dom=$DIR/$tdir/$tfile
22496         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22497
22498         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22499         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22500
22501         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22502         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22503                 error "can't create OST file"
22504         # mirrored file with DOM entry in the second mirror
22505         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22506                 error "can't create mirror with DoM component"
22507
22508         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22509
22510         # DOM component in the middle and has other enries in the same mirror,
22511         # should succeed but lost DoM component
22512         $LFS setstripe --copy=${dom}_1 $dom ||
22513                 error "Can't create file from OST|DOM mirror layout"
22514         # check new file has no DoM layout after all
22515         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22516                 error "File has DoM component while DoM is disabled"
22517 }
22518 run_test 270h "DoM: DoM stripe removal when disabled on server"
22519
22520 test_270i() {
22521         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22522                 skip "Need MDS version at least 2.14.54"
22523
22524         mkdir $DIR/$tdir
22525         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22526                 error "setstripe should fail" || true
22527 }
22528 run_test 270i "DoM: setting invalid DoM striping should fail"
22529
22530 test_271a() {
22531         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22532                 skip "Need MDS version at least 2.10.55"
22533
22534         local dom=$DIR/$tdir/dom
22535
22536         mkdir -p $DIR/$tdir
22537
22538         $LFS setstripe -E 1024K -L mdt $dom
22539
22540         lctl set_param -n mdc.*.stats=clear
22541         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22542         cat $dom > /dev/null
22543         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22544         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22545         ls $dom
22546         rm -f $dom
22547 }
22548 run_test 271a "DoM: data is cached for read after write"
22549
22550 test_271b() {
22551         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22552                 skip "Need MDS version at least 2.10.55"
22553
22554         local dom=$DIR/$tdir/dom
22555
22556         mkdir -p $DIR/$tdir
22557
22558         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22559
22560         lctl set_param -n mdc.*.stats=clear
22561         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22562         cancel_lru_locks mdc
22563         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22564         # second stat to check size is cached on client
22565         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22566         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22567         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22568         rm -f $dom
22569 }
22570 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22571
22572 test_271ba() {
22573         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22574                 skip "Need MDS version at least 2.10.55"
22575
22576         local dom=$DIR/$tdir/dom
22577
22578         mkdir -p $DIR/$tdir
22579
22580         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22581
22582         lctl set_param -n mdc.*.stats=clear
22583         lctl set_param -n osc.*.stats=clear
22584         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22585         cancel_lru_locks mdc
22586         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22587         # second stat to check size is cached on client
22588         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22589         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22590         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22591         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22592         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22593         rm -f $dom
22594 }
22595 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22596
22597
22598 get_mdc_stats() {
22599         local mdtidx=$1
22600         local param=$2
22601         local mdt=MDT$(printf %04x $mdtidx)
22602
22603         if [ -z $param ]; then
22604                 lctl get_param -n mdc.*$mdt*.stats
22605         else
22606                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22607         fi
22608 }
22609
22610 test_271c() {
22611         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22612                 skip "Need MDS version at least 2.10.55"
22613
22614         local dom=$DIR/$tdir/dom
22615
22616         mkdir -p $DIR/$tdir
22617
22618         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22619
22620         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22621         local facet=mds$((mdtidx + 1))
22622
22623         cancel_lru_locks mdc
22624         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22625         createmany -o $dom 1000
22626         lctl set_param -n mdc.*.stats=clear
22627         smalliomany -w $dom 1000 200
22628         get_mdc_stats $mdtidx
22629         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22630         # Each file has 1 open, 1 IO enqueues, total 2000
22631         # but now we have also +1 getxattr for security.capability, total 3000
22632         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22633         unlinkmany $dom 1000
22634
22635         cancel_lru_locks mdc
22636         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22637         createmany -o $dom 1000
22638         lctl set_param -n mdc.*.stats=clear
22639         smalliomany -w $dom 1000 200
22640         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22641         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22642         # for OPEN and IO lock.
22643         [ $((enq - enq_2)) -ge 1000 ] ||
22644                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22645         unlinkmany $dom 1000
22646         return 0
22647 }
22648 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22649
22650 cleanup_271def_tests() {
22651         trap 0
22652         rm -f $1
22653 }
22654
22655 test_271d() {
22656         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22657                 skip "Need MDS version at least 2.10.57"
22658
22659         local dom=$DIR/$tdir/dom
22660         local tmp=$TMP/$tfile
22661         trap "cleanup_271def_tests $tmp" EXIT
22662
22663         mkdir -p $DIR/$tdir
22664
22665         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22666
22667         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22668
22669         cancel_lru_locks mdc
22670         dd if=/dev/urandom of=$tmp bs=1000 count=1
22671         dd if=$tmp of=$dom bs=1000 count=1
22672         cancel_lru_locks mdc
22673
22674         cat /etc/hosts >> $tmp
22675         lctl set_param -n mdc.*.stats=clear
22676
22677         # append data to the same file it should update local page
22678         echo "Append to the same page"
22679         cat /etc/hosts >> $dom
22680         local num=$(get_mdc_stats $mdtidx ost_read)
22681         local ra=$(get_mdc_stats $mdtidx req_active)
22682         local rw=$(get_mdc_stats $mdtidx req_waittime)
22683
22684         [ -z $num ] || error "$num READ RPC occured"
22685         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22686         echo "... DONE"
22687
22688         # compare content
22689         cmp $tmp $dom || error "file miscompare"
22690
22691         cancel_lru_locks mdc
22692         lctl set_param -n mdc.*.stats=clear
22693
22694         echo "Open and read file"
22695         cat $dom > /dev/null
22696         local num=$(get_mdc_stats $mdtidx ost_read)
22697         local ra=$(get_mdc_stats $mdtidx req_active)
22698         local rw=$(get_mdc_stats $mdtidx req_waittime)
22699
22700         [ -z $num ] || error "$num READ RPC occured"
22701         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22702         echo "... DONE"
22703
22704         # compare content
22705         cmp $tmp $dom || error "file miscompare"
22706
22707         return 0
22708 }
22709 run_test 271d "DoM: read on open (1K file in reply buffer)"
22710
22711 test_271f() {
22712         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22713                 skip "Need MDS version at least 2.10.57"
22714
22715         local dom=$DIR/$tdir/dom
22716         local tmp=$TMP/$tfile
22717         trap "cleanup_271def_tests $tmp" EXIT
22718
22719         mkdir -p $DIR/$tdir
22720
22721         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22722
22723         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22724
22725         cancel_lru_locks mdc
22726         dd if=/dev/urandom of=$tmp bs=265000 count=1
22727         dd if=$tmp of=$dom bs=265000 count=1
22728         cancel_lru_locks mdc
22729         cat /etc/hosts >> $tmp
22730         lctl set_param -n mdc.*.stats=clear
22731
22732         echo "Append to the same page"
22733         cat /etc/hosts >> $dom
22734         local num=$(get_mdc_stats $mdtidx ost_read)
22735         local ra=$(get_mdc_stats $mdtidx req_active)
22736         local rw=$(get_mdc_stats $mdtidx req_waittime)
22737
22738         [ -z $num ] || error "$num READ RPC occured"
22739         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22740         echo "... DONE"
22741
22742         # compare content
22743         cmp $tmp $dom || error "file miscompare"
22744
22745         cancel_lru_locks mdc
22746         lctl set_param -n mdc.*.stats=clear
22747
22748         echo "Open and read file"
22749         cat $dom > /dev/null
22750         local num=$(get_mdc_stats $mdtidx ost_read)
22751         local ra=$(get_mdc_stats $mdtidx req_active)
22752         local rw=$(get_mdc_stats $mdtidx req_waittime)
22753
22754         [ -z $num ] && num=0
22755         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22756         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22757         echo "... DONE"
22758
22759         # compare content
22760         cmp $tmp $dom || error "file miscompare"
22761
22762         return 0
22763 }
22764 run_test 271f "DoM: read on open (200K file and read tail)"
22765
22766 test_271g() {
22767         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22768                 skip "Skipping due to old client or server version"
22769
22770         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22771         # to get layout
22772         $CHECKSTAT -t file $DIR1/$tfile
22773
22774         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22775         MULTIOP_PID=$!
22776         sleep 1
22777         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22778         $LCTL set_param fail_loc=0x80000314
22779         rm $DIR1/$tfile || error "Unlink fails"
22780         RC=$?
22781         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22782         [ $RC -eq 0 ] || error "Failed write to stale object"
22783 }
22784 run_test 271g "Discard DoM data vs client flush race"
22785
22786 test_272a() {
22787         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22788                 skip "Need MDS version at least 2.11.50"
22789
22790         local dom=$DIR/$tdir/dom
22791         mkdir -p $DIR/$tdir
22792
22793         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22794         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22795                 error "failed to write data into $dom"
22796         local old_md5=$(md5sum $dom)
22797
22798         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22799                 error "failed to migrate to the same DoM component"
22800
22801         local new_md5=$(md5sum $dom)
22802
22803         [ "$old_md5" == "$new_md5" ] ||
22804                 error "md5sum differ: $old_md5, $new_md5"
22805
22806         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22807                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22808 }
22809 run_test 272a "DoM migration: new layout with the same DOM component"
22810
22811 test_272b() {
22812         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22813                 skip "Need MDS version at least 2.11.50"
22814
22815         local dom=$DIR/$tdir/dom
22816         mkdir -p $DIR/$tdir
22817         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22818
22819         local mdtidx=$($LFS getstripe -m $dom)
22820         local mdtname=MDT$(printf %04x $mdtidx)
22821         local facet=mds$((mdtidx + 1))
22822
22823         local mdtfree1=$(do_facet $facet \
22824                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22825         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22826                 error "failed to write data into $dom"
22827         local old_md5=$(md5sum $dom)
22828         cancel_lru_locks mdc
22829         local mdtfree1=$(do_facet $facet \
22830                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22831
22832         $LFS migrate -c2 $dom ||
22833                 error "failed to migrate to the new composite layout"
22834         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22835                 error "MDT stripe was not removed"
22836
22837         cancel_lru_locks mdc
22838         local new_md5=$(md5sum $dom)
22839         [ "$old_md5" == "$new_md5" ] ||
22840                 error "$old_md5 != $new_md5"
22841
22842         # Skip free space checks with ZFS
22843         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22844                 local mdtfree2=$(do_facet $facet \
22845                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22846                 [ $mdtfree2 -gt $mdtfree1 ] ||
22847                         error "MDT space is not freed after migration"
22848         fi
22849         return 0
22850 }
22851 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22852
22853 test_272c() {
22854         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22855                 skip "Need MDS version at least 2.11.50"
22856
22857         local dom=$DIR/$tdir/$tfile
22858         mkdir -p $DIR/$tdir
22859         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22860
22861         local mdtidx=$($LFS getstripe -m $dom)
22862         local mdtname=MDT$(printf %04x $mdtidx)
22863         local facet=mds$((mdtidx + 1))
22864
22865         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22866                 error "failed to write data into $dom"
22867         local old_md5=$(md5sum $dom)
22868         cancel_lru_locks mdc
22869         local mdtfree1=$(do_facet $facet \
22870                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22871
22872         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22873                 error "failed to migrate to the new composite layout"
22874         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22875                 error "MDT stripe was not removed"
22876
22877         cancel_lru_locks mdc
22878         local new_md5=$(md5sum $dom)
22879         [ "$old_md5" == "$new_md5" ] ||
22880                 error "$old_md5 != $new_md5"
22881
22882         # Skip free space checks with ZFS
22883         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22884                 local mdtfree2=$(do_facet $facet \
22885                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22886                 [ $mdtfree2 -gt $mdtfree1 ] ||
22887                         error "MDS space is not freed after migration"
22888         fi
22889         return 0
22890 }
22891 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22892
22893 test_272d() {
22894         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22895                 skip "Need MDS version at least 2.12.55"
22896
22897         local dom=$DIR/$tdir/$tfile
22898         mkdir -p $DIR/$tdir
22899         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22900
22901         local mdtidx=$($LFS getstripe -m $dom)
22902         local mdtname=MDT$(printf %04x $mdtidx)
22903         local facet=mds$((mdtidx + 1))
22904
22905         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22906                 error "failed to write data into $dom"
22907         local old_md5=$(md5sum $dom)
22908         cancel_lru_locks mdc
22909         local mdtfree1=$(do_facet $facet \
22910                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22911
22912         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22913                 error "failed mirroring to the new composite layout"
22914         $LFS mirror resync $dom ||
22915                 error "failed mirror resync"
22916         $LFS mirror split --mirror-id 1 -d $dom ||
22917                 error "failed mirror split"
22918
22919         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22920                 error "MDT stripe was not removed"
22921
22922         cancel_lru_locks mdc
22923         local new_md5=$(md5sum $dom)
22924         [ "$old_md5" == "$new_md5" ] ||
22925                 error "$old_md5 != $new_md5"
22926
22927         # Skip free space checks with ZFS
22928         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22929                 local mdtfree2=$(do_facet $facet \
22930                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22931                 [ $mdtfree2 -gt $mdtfree1 ] ||
22932                         error "MDS space is not freed after DOM mirror deletion"
22933         fi
22934         return 0
22935 }
22936 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22937
22938 test_272e() {
22939         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22940                 skip "Need MDS version at least 2.12.55"
22941
22942         local dom=$DIR/$tdir/$tfile
22943         mkdir -p $DIR/$tdir
22944         $LFS setstripe -c 2 $dom
22945
22946         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22947                 error "failed to write data into $dom"
22948         local old_md5=$(md5sum $dom)
22949         cancel_lru_locks
22950
22951         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22952                 error "failed mirroring to the DOM layout"
22953         $LFS mirror resync $dom ||
22954                 error "failed mirror resync"
22955         $LFS mirror split --mirror-id 1 -d $dom ||
22956                 error "failed mirror split"
22957
22958         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22959                 error "MDT stripe wasn't set"
22960
22961         cancel_lru_locks
22962         local new_md5=$(md5sum $dom)
22963         [ "$old_md5" == "$new_md5" ] ||
22964                 error "$old_md5 != $new_md5"
22965
22966         return 0
22967 }
22968 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22969
22970 test_272f() {
22971         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22972                 skip "Need MDS version at least 2.12.55"
22973
22974         local dom=$DIR/$tdir/$tfile
22975         mkdir -p $DIR/$tdir
22976         $LFS setstripe -c 2 $dom
22977
22978         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22979                 error "failed to write data into $dom"
22980         local old_md5=$(md5sum $dom)
22981         cancel_lru_locks
22982
22983         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22984                 error "failed migrating to the DOM file"
22985
22986         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22987                 error "MDT stripe wasn't set"
22988
22989         cancel_lru_locks
22990         local new_md5=$(md5sum $dom)
22991         [ "$old_md5" != "$new_md5" ] &&
22992                 error "$old_md5 != $new_md5"
22993
22994         return 0
22995 }
22996 run_test 272f "DoM migration: OST-striped file to DOM file"
22997
22998 test_273a() {
22999         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23000                 skip "Need MDS version at least 2.11.50"
23001
23002         # Layout swap cannot be done if either file has DOM component,
23003         # this will never be supported, migration should be used instead
23004
23005         local dom=$DIR/$tdir/$tfile
23006         mkdir -p $DIR/$tdir
23007
23008         $LFS setstripe -c2 ${dom}_plain
23009         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23010         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23011                 error "can swap layout with DoM component"
23012         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23013                 error "can swap layout with DoM component"
23014
23015         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23016         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23017                 error "can swap layout with DoM component"
23018         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23019                 error "can swap layout with DoM component"
23020         return 0
23021 }
23022 run_test 273a "DoM: layout swapping should fail with DOM"
23023
23024 test_273b() {
23025         mkdir -p $DIR/$tdir
23026         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23027
23028 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23029         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23030
23031         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23032 }
23033 run_test 273b "DoM: race writeback and object destroy"
23034
23035 test_275() {
23036         remote_ost_nodsh && skip "remote OST with nodsh"
23037         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23038                 skip "Need OST version >= 2.10.57"
23039
23040         local file=$DIR/$tfile
23041         local oss
23042
23043         oss=$(comma_list $(osts_nodes))
23044
23045         dd if=/dev/urandom of=$file bs=1M count=2 ||
23046                 error "failed to create a file"
23047         cancel_lru_locks osc
23048
23049         #lock 1
23050         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23051                 error "failed to read a file"
23052
23053 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23054         $LCTL set_param fail_loc=0x8000031f
23055
23056         cancel_lru_locks osc &
23057         sleep 1
23058
23059 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23060         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23061         #IO takes another lock, but matches the PENDING one
23062         #and places it to the IO RPC
23063         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23064                 error "failed to read a file with PENDING lock"
23065 }
23066 run_test 275 "Read on a canceled duplicate lock"
23067
23068 test_276() {
23069         remote_ost_nodsh && skip "remote OST with nodsh"
23070         local pid
23071
23072         do_facet ost1 "(while true; do \
23073                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23074                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23075         pid=$!
23076
23077         for LOOP in $(seq 20); do
23078                 stop ost1
23079                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23080         done
23081         kill -9 $pid
23082         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23083                 rm $TMP/sanity_276_pid"
23084 }
23085 run_test 276 "Race between mount and obd_statfs"
23086
23087 test_277() {
23088         $LCTL set_param ldlm.namespaces.*.lru_size=0
23089         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23090         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23091                         grep ^used_mb | awk '{print $2}')
23092         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23093         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23094                 oflag=direct conv=notrunc
23095         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23096                         grep ^used_mb | awk '{print $2}')
23097         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23098 }
23099 run_test 277 "Direct IO shall drop page cache"
23100
23101 test_278() {
23102         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23103         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23104         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23105                 skip "needs the same host for mdt1 mdt2" && return
23106
23107         local pid1
23108         local pid2
23109
23110 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23111         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23112         stop mds2 &
23113         pid2=$!
23114
23115         stop mds1
23116
23117         echo "Starting MDTs"
23118         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23119         wait $pid2
23120 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23121 #will return NULL
23122         do_facet mds2 $LCTL set_param fail_loc=0
23123
23124         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23125         wait_recovery_complete mds2
23126 }
23127 run_test 278 "Race starting MDS between MDTs stop/start"
23128
23129 test_280() {
23130         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23131                 skip "Need MGS version at least 2.13.52"
23132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23133         combined_mgs_mds || skip "needs combined MGS/MDT"
23134
23135         umount_client $MOUNT
23136 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23137         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23138
23139         mount_client $MOUNT &
23140         sleep 1
23141         stop mgs || error "stop mgs failed"
23142         #for a race mgs would crash
23143         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23144         # make sure we unmount client before remounting
23145         wait
23146         umount_client $MOUNT
23147         mount_client $MOUNT || error "mount client failed"
23148 }
23149 run_test 280 "Race between MGS umount and client llog processing"
23150
23151 cleanup_test_300() {
23152         trap 0
23153         umask $SAVE_UMASK
23154 }
23155 test_striped_dir() {
23156         local mdt_index=$1
23157         local stripe_count
23158         local stripe_index
23159
23160         mkdir -p $DIR/$tdir
23161
23162         SAVE_UMASK=$(umask)
23163         trap cleanup_test_300 RETURN EXIT
23164
23165         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23166                                                 $DIR/$tdir/striped_dir ||
23167                 error "set striped dir error"
23168
23169         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23170         [ "$mode" = "755" ] || error "expect 755 got $mode"
23171
23172         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23173                 error "getdirstripe failed"
23174         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23175         if [ "$stripe_count" != "2" ]; then
23176                 error "1:stripe_count is $stripe_count, expect 2"
23177         fi
23178         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23179         if [ "$stripe_count" != "2" ]; then
23180                 error "2:stripe_count is $stripe_count, expect 2"
23181         fi
23182
23183         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23184         if [ "$stripe_index" != "$mdt_index" ]; then
23185                 error "stripe_index is $stripe_index, expect $mdt_index"
23186         fi
23187
23188         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23189                 error "nlink error after create striped dir"
23190
23191         mkdir $DIR/$tdir/striped_dir/a
23192         mkdir $DIR/$tdir/striped_dir/b
23193
23194         stat $DIR/$tdir/striped_dir/a ||
23195                 error "create dir under striped dir failed"
23196         stat $DIR/$tdir/striped_dir/b ||
23197                 error "create dir under striped dir failed"
23198
23199         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23200                 error "nlink error after mkdir"
23201
23202         rmdir $DIR/$tdir/striped_dir/a
23203         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23204                 error "nlink error after rmdir"
23205
23206         rmdir $DIR/$tdir/striped_dir/b
23207         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23208                 error "nlink error after rmdir"
23209
23210         chattr +i $DIR/$tdir/striped_dir
23211         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23212                 error "immutable flags not working under striped dir!"
23213         chattr -i $DIR/$tdir/striped_dir
23214
23215         rmdir $DIR/$tdir/striped_dir ||
23216                 error "rmdir striped dir error"
23217
23218         cleanup_test_300
23219
23220         true
23221 }
23222
23223 test_300a() {
23224         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23225                 skip "skipped for lustre < 2.7.0"
23226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23227         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23228
23229         test_striped_dir 0 || error "failed on striped dir on MDT0"
23230         test_striped_dir 1 || error "failed on striped dir on MDT0"
23231 }
23232 run_test 300a "basic striped dir sanity test"
23233
23234 test_300b() {
23235         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23236                 skip "skipped for lustre < 2.7.0"
23237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23238         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23239
23240         local i
23241         local mtime1
23242         local mtime2
23243         local mtime3
23244
23245         test_mkdir $DIR/$tdir || error "mkdir fail"
23246         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23247                 error "set striped dir error"
23248         for i in {0..9}; do
23249                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23250                 sleep 1
23251                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23252                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23253                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23254                 sleep 1
23255                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23256                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23257                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23258         done
23259         true
23260 }
23261 run_test 300b "check ctime/mtime for striped dir"
23262
23263 test_300c() {
23264         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23265                 skip "skipped for lustre < 2.7.0"
23266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23267         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23268
23269         local file_count
23270
23271         mkdir_on_mdt0 $DIR/$tdir
23272         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23273                 error "set striped dir error"
23274
23275         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23276                 error "chown striped dir failed"
23277
23278         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23279                 error "create 5k files failed"
23280
23281         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23282
23283         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23284
23285         rm -rf $DIR/$tdir
23286 }
23287 run_test 300c "chown && check ls under striped directory"
23288
23289 test_300d() {
23290         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23291                 skip "skipped for lustre < 2.7.0"
23292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23293         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23294
23295         local stripe_count
23296         local file
23297
23298         mkdir -p $DIR/$tdir
23299         $LFS setstripe -c 2 $DIR/$tdir
23300
23301         #local striped directory
23302         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23303                 error "set striped dir error"
23304         #look at the directories for debug purposes
23305         ls -l $DIR/$tdir
23306         $LFS getdirstripe $DIR/$tdir
23307         ls -l $DIR/$tdir/striped_dir
23308         $LFS getdirstripe $DIR/$tdir/striped_dir
23309         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23310                 error "create 10 files failed"
23311
23312         #remote striped directory
23313         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23314                 error "set striped dir error"
23315         #look at the directories for debug purposes
23316         ls -l $DIR/$tdir
23317         $LFS getdirstripe $DIR/$tdir
23318         ls -l $DIR/$tdir/remote_striped_dir
23319         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23320         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23321                 error "create 10 files failed"
23322
23323         for file in $(find $DIR/$tdir); do
23324                 stripe_count=$($LFS getstripe -c $file)
23325                 [ $stripe_count -eq 2 ] ||
23326                         error "wrong stripe $stripe_count for $file"
23327         done
23328
23329         rm -rf $DIR/$tdir
23330 }
23331 run_test 300d "check default stripe under striped directory"
23332
23333 test_300e() {
23334         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23335                 skip "Need MDS version at least 2.7.55"
23336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23338
23339         local stripe_count
23340         local file
23341
23342         mkdir -p $DIR/$tdir
23343
23344         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23345                 error "set striped dir error"
23346
23347         touch $DIR/$tdir/striped_dir/a
23348         touch $DIR/$tdir/striped_dir/b
23349         touch $DIR/$tdir/striped_dir/c
23350
23351         mkdir $DIR/$tdir/striped_dir/dir_a
23352         mkdir $DIR/$tdir/striped_dir/dir_b
23353         mkdir $DIR/$tdir/striped_dir/dir_c
23354
23355         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23356                 error "set striped adir under striped dir error"
23357
23358         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23359                 error "set striped bdir under striped dir error"
23360
23361         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23362                 error "set striped cdir under striped dir error"
23363
23364         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23365                 error "rename dir under striped dir fails"
23366
23367         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23368                 error "rename dir under different stripes fails"
23369
23370         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23371                 error "rename file under striped dir should succeed"
23372
23373         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23374                 error "rename dir under striped dir should succeed"
23375
23376         rm -rf $DIR/$tdir
23377 }
23378 run_test 300e "check rename under striped directory"
23379
23380 test_300f() {
23381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23383         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23384                 skip "Need MDS version at least 2.7.55"
23385
23386         local stripe_count
23387         local file
23388
23389         rm -rf $DIR/$tdir
23390         mkdir -p $DIR/$tdir
23391
23392         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23393                 error "set striped dir error"
23394
23395         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23396                 error "set striped dir error"
23397
23398         touch $DIR/$tdir/striped_dir/a
23399         mkdir $DIR/$tdir/striped_dir/dir_a
23400         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23401                 error "create striped dir under striped dir fails"
23402
23403         touch $DIR/$tdir/striped_dir1/b
23404         mkdir $DIR/$tdir/striped_dir1/dir_b
23405         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23406                 error "create striped dir under striped dir fails"
23407
23408         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23409                 error "rename dir under different striped dir should fail"
23410
23411         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23412                 error "rename striped dir under diff striped dir should fail"
23413
23414         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23415                 error "rename file under diff striped dirs fails"
23416
23417         rm -rf $DIR/$tdir
23418 }
23419 run_test 300f "check rename cross striped directory"
23420
23421 test_300_check_default_striped_dir()
23422 {
23423         local dirname=$1
23424         local default_count=$2
23425         local default_index=$3
23426         local stripe_count
23427         local stripe_index
23428         local dir_stripe_index
23429         local dir
23430
23431         echo "checking $dirname $default_count $default_index"
23432         $LFS setdirstripe -D -c $default_count -i $default_index \
23433                                 -H all_char $DIR/$tdir/$dirname ||
23434                 error "set default stripe on striped dir error"
23435         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23436         [ $stripe_count -eq $default_count ] ||
23437                 error "expect $default_count get $stripe_count for $dirname"
23438
23439         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23440         [ $stripe_index -eq $default_index ] ||
23441                 error "expect $default_index get $stripe_index for $dirname"
23442
23443         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23444                                                 error "create dirs failed"
23445
23446         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23447         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23448         for dir in $(find $DIR/$tdir/$dirname/*); do
23449                 stripe_count=$($LFS getdirstripe -c $dir)
23450                 (( $stripe_count == $default_count )) ||
23451                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23452                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23453                 error "stripe count $default_count != $stripe_count for $dir"
23454
23455                 stripe_index=$($LFS getdirstripe -i $dir)
23456                 [ $default_index -eq -1 ] ||
23457                         [ $stripe_index -eq $default_index ] ||
23458                         error "$stripe_index != $default_index for $dir"
23459
23460                 #check default stripe
23461                 stripe_count=$($LFS getdirstripe -D -c $dir)
23462                 [ $stripe_count -eq $default_count ] ||
23463                 error "default count $default_count != $stripe_count for $dir"
23464
23465                 stripe_index=$($LFS getdirstripe -D -i $dir)
23466                 [ $stripe_index -eq $default_index ] ||
23467                 error "default index $default_index != $stripe_index for $dir"
23468         done
23469         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23470 }
23471
23472 test_300g() {
23473         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23474         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23475                 skip "Need MDS version at least 2.7.55"
23476
23477         local dir
23478         local stripe_count
23479         local stripe_index
23480
23481         mkdir_on_mdt0 $DIR/$tdir
23482         mkdir $DIR/$tdir/normal_dir
23483
23484         #Checking when client cache stripe index
23485         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23486         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23487                 error "create striped_dir failed"
23488
23489         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23490                 error "create dir0 fails"
23491         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23492         [ $stripe_index -eq 0 ] ||
23493                 error "dir0 expect index 0 got $stripe_index"
23494
23495         mkdir $DIR/$tdir/striped_dir/dir1 ||
23496                 error "create dir1 fails"
23497         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23498         [ $stripe_index -eq 1 ] ||
23499                 error "dir1 expect index 1 got $stripe_index"
23500
23501         #check default stripe count/stripe index
23502         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23503         test_300_check_default_striped_dir normal_dir 1 0
23504         test_300_check_default_striped_dir normal_dir -1 1
23505         test_300_check_default_striped_dir normal_dir 2 -1
23506
23507         #delete default stripe information
23508         echo "delete default stripeEA"
23509         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23510                 error "set default stripe on striped dir error"
23511
23512         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23513         for dir in $(find $DIR/$tdir/normal_dir/*); do
23514                 stripe_count=$($LFS getdirstripe -c $dir)
23515                 [ $stripe_count -eq 0 ] ||
23516                         error "expect 1 get $stripe_count for $dir"
23517         done
23518 }
23519 run_test 300g "check default striped directory for normal directory"
23520
23521 test_300h() {
23522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23523         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23524                 skip "Need MDS version at least 2.7.55"
23525
23526         local dir
23527         local stripe_count
23528
23529         mkdir $DIR/$tdir
23530         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23531                 error "set striped dir error"
23532
23533         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23534         test_300_check_default_striped_dir striped_dir 1 0
23535         test_300_check_default_striped_dir striped_dir -1 1
23536         test_300_check_default_striped_dir striped_dir 2 -1
23537
23538         #delete default stripe information
23539         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23540                 error "set default stripe on striped dir error"
23541
23542         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23543         for dir in $(find $DIR/$tdir/striped_dir/*); do
23544                 stripe_count=$($LFS getdirstripe -c $dir)
23545                 [ $stripe_count -eq 0 ] ||
23546                         error "expect 1 get $stripe_count for $dir"
23547         done
23548 }
23549 run_test 300h "check default striped directory for striped directory"
23550
23551 test_300i() {
23552         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
23553         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23554         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
23555                 skip "Need MDS version at least 2.7.55"
23556
23557         local stripe_count
23558         local file
23559
23560         mkdir $DIR/$tdir
23561
23562         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23563                 error "set striped dir error"
23564
23565         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23566                 error "create files under striped dir failed"
23567
23568         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23569                 error "set striped hashdir error"
23570
23571         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23572                 error "create dir0 under hash dir failed"
23573         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23574                 error "create dir1 under hash dir failed"
23575         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23576                 error "create dir2 under hash dir failed"
23577
23578         # unfortunately, we need to umount to clear dir layout cache for now
23579         # once we fully implement dir layout, we can drop this
23580         umount_client $MOUNT || error "umount failed"
23581         mount_client $MOUNT || error "mount failed"
23582
23583         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23584         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23585         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
23586
23587         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
23588                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
23589                         error "create crush2 dir $tdir/hashdir/d3 failed"
23590                 $LFS find -H crush2 $DIR/$tdir/hashdir
23591                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
23592                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
23593
23594                 # mkdir with an invalid hash type (hash=fail_val) from client
23595                 # should be replaced on MDS with a valid (default) hash type
23596                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23597                 $LCTL set_param fail_loc=0x1901 fail_val=99
23598                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
23599
23600                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
23601                 local expect=$(do_facet mds1 \
23602                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
23603                 [[ $hash == $expect ]] ||
23604                         error "d99 hash '$hash' != expected hash '$expect'"
23605         fi
23606
23607         #set the stripe to be unknown hash type on read
23608         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
23609         $LCTL set_param fail_loc=0x1901 fail_val=99
23610         for ((i = 0; i < 10; i++)); do
23611                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23612                         error "stat f-$i failed"
23613                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23614         done
23615
23616         touch $DIR/$tdir/striped_dir/f0 &&
23617                 error "create under striped dir with unknown hash should fail"
23618
23619         $LCTL set_param fail_loc=0
23620
23621         umount_client $MOUNT || error "umount failed"
23622         mount_client $MOUNT || error "mount failed"
23623
23624         return 0
23625 }
23626 run_test 300i "client handle unknown hash type striped directory"
23627
23628 test_300j() {
23629         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23631         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23632                 skip "Need MDS version at least 2.7.55"
23633
23634         local stripe_count
23635         local file
23636
23637         mkdir $DIR/$tdir
23638
23639         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23640         $LCTL set_param fail_loc=0x1702
23641         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23642                 error "set striped dir error"
23643
23644         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23645                 error "create files under striped dir failed"
23646
23647         $LCTL set_param fail_loc=0
23648
23649         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23650
23651         return 0
23652 }
23653 run_test 300j "test large update record"
23654
23655 test_300k() {
23656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23657         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23658         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23659                 skip "Need MDS version at least 2.7.55"
23660
23661         # this test needs a huge transaction
23662         local kb
23663         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23664              osd*.$FSNAME-MDT0000.kbytestotal")
23665         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23666
23667         local stripe_count
23668         local file
23669
23670         mkdir $DIR/$tdir
23671
23672         #define OBD_FAIL_LARGE_STRIPE   0x1703
23673         $LCTL set_param fail_loc=0x1703
23674         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23675                 error "set striped dir error"
23676         $LCTL set_param fail_loc=0
23677
23678         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23679                 error "getstripeddir fails"
23680         rm -rf $DIR/$tdir/striped_dir ||
23681                 error "unlink striped dir fails"
23682
23683         return 0
23684 }
23685 run_test 300k "test large striped directory"
23686
23687 test_300l() {
23688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23689         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23690         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23691                 skip "Need MDS version at least 2.7.55"
23692
23693         local stripe_index
23694
23695         test_mkdir -p $DIR/$tdir/striped_dir
23696         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23697                         error "chown $RUNAS_ID failed"
23698         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23699                 error "set default striped dir failed"
23700
23701         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23702         $LCTL set_param fail_loc=0x80000158
23703         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23704
23705         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23706         [ $stripe_index -eq 1 ] ||
23707                 error "expect 1 get $stripe_index for $dir"
23708 }
23709 run_test 300l "non-root user to create dir under striped dir with stale layout"
23710
23711 test_300m() {
23712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23713         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23714         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23715                 skip "Need MDS version at least 2.7.55"
23716
23717         mkdir -p $DIR/$tdir/striped_dir
23718         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23719                 error "set default stripes dir error"
23720
23721         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23722
23723         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23724         [ $stripe_count -eq 0 ] ||
23725                         error "expect 0 get $stripe_count for a"
23726
23727         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23728                 error "set default stripes dir error"
23729
23730         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23731
23732         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23733         [ $stripe_count -eq 0 ] ||
23734                         error "expect 0 get $stripe_count for b"
23735
23736         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23737                 error "set default stripes dir error"
23738
23739         mkdir $DIR/$tdir/striped_dir/c &&
23740                 error "default stripe_index is invalid, mkdir c should fails"
23741
23742         rm -rf $DIR/$tdir || error "rmdir fails"
23743 }
23744 run_test 300m "setstriped directory on single MDT FS"
23745
23746 cleanup_300n() {
23747         local list=$(comma_list $(mdts_nodes))
23748
23749         trap 0
23750         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23751 }
23752
23753 test_300n() {
23754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23755         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23756         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23757                 skip "Need MDS version at least 2.7.55"
23758         remote_mds_nodsh && skip "remote MDS with nodsh"
23759
23760         local stripe_index
23761         local list=$(comma_list $(mdts_nodes))
23762
23763         trap cleanup_300n RETURN EXIT
23764         mkdir -p $DIR/$tdir
23765         chmod 777 $DIR/$tdir
23766         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23767                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23768                 error "create striped dir succeeds with gid=0"
23769
23770         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23771         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23772                 error "create striped dir fails with gid=-1"
23773
23774         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23775         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23776                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23777                 error "set default striped dir succeeds with gid=0"
23778
23779
23780         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23781         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23782                 error "set default striped dir fails with gid=-1"
23783
23784
23785         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23786         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23787                                         error "create test_dir fails"
23788         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23789                                         error "create test_dir1 fails"
23790         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23791                                         error "create test_dir2 fails"
23792         cleanup_300n
23793 }
23794 run_test 300n "non-root user to create dir under striped dir with default EA"
23795
23796 test_300o() {
23797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23799         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23800                 skip "Need MDS version at least 2.7.55"
23801
23802         local numfree1
23803         local numfree2
23804
23805         mkdir -p $DIR/$tdir
23806
23807         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23808         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23809         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23810                 skip "not enough free inodes $numfree1 $numfree2"
23811         fi
23812
23813         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23814         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23815         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23816                 skip "not enough free space $numfree1 $numfree2"
23817         fi
23818
23819         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23820                 error "setdirstripe fails"
23821
23822         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23823                 error "create dirs fails"
23824
23825         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23826         ls $DIR/$tdir/striped_dir > /dev/null ||
23827                 error "ls striped dir fails"
23828         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23829                 error "unlink big striped dir fails"
23830 }
23831 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23832
23833 test_300p() {
23834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23836         remote_mds_nodsh && skip "remote MDS with nodsh"
23837
23838         mkdir_on_mdt0 $DIR/$tdir
23839
23840         #define OBD_FAIL_OUT_ENOSPC     0x1704
23841         do_facet mds2 lctl set_param fail_loc=0x80001704
23842         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23843                  && error "create striped directory should fail"
23844
23845         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23846
23847         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23848         true
23849 }
23850 run_test 300p "create striped directory without space"
23851
23852 test_300q() {
23853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23855
23856         local fd=$(free_fd)
23857         local cmd="exec $fd<$tdir"
23858         cd $DIR
23859         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23860         eval $cmd
23861         cmd="exec $fd<&-"
23862         trap "eval $cmd" EXIT
23863         cd $tdir || error "cd $tdir fails"
23864         rmdir  ../$tdir || error "rmdir $tdir fails"
23865         mkdir local_dir && error "create dir succeeds"
23866         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23867         eval $cmd
23868         return 0
23869 }
23870 run_test 300q "create remote directory under orphan directory"
23871
23872 test_300r() {
23873         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23874                 skip "Need MDS version at least 2.7.55" && return
23875         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23876
23877         mkdir $DIR/$tdir
23878
23879         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23880                 error "set striped dir error"
23881
23882         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23883                 error "getstripeddir fails"
23884
23885         local stripe_count
23886         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23887                       awk '/lmv_stripe_count:/ { print $2 }')
23888
23889         [ $MDSCOUNT -ne $stripe_count ] &&
23890                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23891
23892         rm -rf $DIR/$tdir/striped_dir ||
23893                 error "unlink striped dir fails"
23894 }
23895 run_test 300r "test -1 striped directory"
23896
23897 test_300s_helper() {
23898         local count=$1
23899
23900         local stripe_dir=$DIR/$tdir/striped_dir.$count
23901
23902         $LFS mkdir -c $count $stripe_dir ||
23903                 error "lfs mkdir -c error"
23904
23905         $LFS getdirstripe $stripe_dir ||
23906                 error "lfs getdirstripe fails"
23907
23908         local stripe_count
23909         stripe_count=$($LFS getdirstripe $stripe_dir |
23910                       awk '/lmv_stripe_count:/ { print $2 }')
23911
23912         [ $count -ne $stripe_count ] &&
23913                 error_noexit "bad stripe count $stripe_count expected $count"
23914
23915         local dupe_stripes
23916         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23917                 awk '/0x/ {count[$1] += 1}; END {
23918                         for (idx in count) {
23919                                 if (count[idx]>1) {
23920                                         print "index " idx " count " count[idx]
23921                                 }
23922                         }
23923                 }')
23924
23925         if [[ -n "$dupe_stripes" ]] ; then
23926                 lfs getdirstripe $stripe_dir
23927                 error_noexit "Dupe MDT above: $dupe_stripes "
23928         fi
23929
23930         rm -rf $stripe_dir ||
23931                 error_noexit "unlink $stripe_dir fails"
23932 }
23933
23934 test_300s() {
23935         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23936                 skip "Need MDS version at least 2.7.55" && return
23937         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23938
23939         mkdir $DIR/$tdir
23940         for count in $(seq 2 $MDSCOUNT); do
23941                 test_300s_helper $count
23942         done
23943 }
23944 run_test 300s "test lfs mkdir -c without -i"
23945
23946 test_300t() {
23947         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23948                 skip "need MDS 2.14.55 or later"
23949         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23950
23951         local testdir="$DIR/$tdir/striped_dir"
23952         local dir1=$testdir/dir1
23953         local dir2=$testdir/dir2
23954
23955         mkdir -p $testdir
23956
23957         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23958                 error "failed to set default stripe count for $testdir"
23959
23960         mkdir $dir1
23961         local stripe_count=$($LFS getdirstripe -c $dir1)
23962
23963         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23964
23965         local max_count=$((MDSCOUNT - 1))
23966         local mdts=$(comma_list $(mdts_nodes))
23967
23968         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23969         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23970
23971         mkdir $dir2
23972         stripe_count=$($LFS getdirstripe -c $dir2)
23973
23974         (( $stripe_count == $max_count )) || error "wrong stripe count"
23975 }
23976 run_test 300t "test max_mdt_stripecount"
23977
23978 prepare_remote_file() {
23979         mkdir $DIR/$tdir/src_dir ||
23980                 error "create remote source failed"
23981
23982         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23983                  error "cp to remote source failed"
23984         touch $DIR/$tdir/src_dir/a
23985
23986         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23987                 error "create remote target dir failed"
23988
23989         touch $DIR/$tdir/tgt_dir/b
23990
23991         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23992                 error "rename dir cross MDT failed!"
23993
23994         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23995                 error "src_child still exists after rename"
23996
23997         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23998                 error "missing file(a) after rename"
23999
24000         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24001                 error "diff after rename"
24002 }
24003
24004 test_310a() {
24005         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24007
24008         local remote_file=$DIR/$tdir/tgt_dir/b
24009
24010         mkdir -p $DIR/$tdir
24011
24012         prepare_remote_file || error "prepare remote file failed"
24013
24014         #open-unlink file
24015         $OPENUNLINK $remote_file $remote_file ||
24016                 error "openunlink $remote_file failed"
24017         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24018 }
24019 run_test 310a "open unlink remote file"
24020
24021 test_310b() {
24022         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24024
24025         local remote_file=$DIR/$tdir/tgt_dir/b
24026
24027         mkdir -p $DIR/$tdir
24028
24029         prepare_remote_file || error "prepare remote file failed"
24030
24031         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24032         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24033         $CHECKSTAT -t file $remote_file || error "check file failed"
24034 }
24035 run_test 310b "unlink remote file with multiple links while open"
24036
24037 test_310c() {
24038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24039         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24040
24041         local remote_file=$DIR/$tdir/tgt_dir/b
24042
24043         mkdir -p $DIR/$tdir
24044
24045         prepare_remote_file || error "prepare remote file failed"
24046
24047         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24048         multiop_bg_pause $remote_file O_uc ||
24049                         error "mulitop failed for remote file"
24050         MULTIPID=$!
24051         $MULTIOP $DIR/$tfile Ouc
24052         kill -USR1 $MULTIPID
24053         wait $MULTIPID
24054 }
24055 run_test 310c "open-unlink remote file with multiple links"
24056
24057 #LU-4825
24058 test_311() {
24059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24060         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24061         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24062                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24063         remote_mds_nodsh && skip "remote MDS with nodsh"
24064
24065         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24066         local mdts=$(comma_list $(mdts_nodes))
24067
24068         mkdir -p $DIR/$tdir
24069         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24070         createmany -o $DIR/$tdir/$tfile. 1000
24071
24072         # statfs data is not real time, let's just calculate it
24073         old_iused=$((old_iused + 1000))
24074
24075         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24076                         osp.*OST0000*MDT0000.create_count")
24077         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24078                                 osp.*OST0000*MDT0000.max_create_count")
24079         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24080
24081         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24082         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24083         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24084
24085         unlinkmany $DIR/$tdir/$tfile. 1000
24086
24087         do_nodes $mdts "$LCTL set_param -n \
24088                         osp.*OST0000*.max_create_count=$max_count"
24089         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24090                 do_nodes $mdts "$LCTL set_param -n \
24091                                 osp.*OST0000*.create_count=$count"
24092         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24093                         grep "=0" && error "create_count is zero"
24094
24095         local new_iused
24096         for i in $(seq 120); do
24097                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24098                 # system may be too busy to destroy all objs in time, use
24099                 # a somewhat small value to not fail autotest
24100                 [ $((old_iused - new_iused)) -gt 400 ] && break
24101                 sleep 1
24102         done
24103
24104         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24105         [ $((old_iused - new_iused)) -gt 400 ] ||
24106                 error "objs not destroyed after unlink"
24107 }
24108 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24109
24110 zfs_oid_to_objid()
24111 {
24112         local ost=$1
24113         local objid=$2
24114
24115         local vdevdir=$(dirname $(facet_vdevice $ost))
24116         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24117         local zfs_zapid=$(do_facet $ost $cmd |
24118                           grep -w "/O/0/d$((objid%32))" -C 5 |
24119                           awk '/Object/{getline; print $1}')
24120         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24121                           awk "/$objid = /"'{printf $3}')
24122
24123         echo $zfs_objid
24124 }
24125
24126 zfs_object_blksz() {
24127         local ost=$1
24128         local objid=$2
24129
24130         local vdevdir=$(dirname $(facet_vdevice $ost))
24131         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24132         local blksz=$(do_facet $ost $cmd $objid |
24133                       awk '/dblk/{getline; printf $4}')
24134
24135         case "${blksz: -1}" in
24136                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24137                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24138                 *) ;;
24139         esac
24140
24141         echo $blksz
24142 }
24143
24144 test_312() { # LU-4856
24145         remote_ost_nodsh && skip "remote OST with nodsh"
24146         [ "$ost1_FSTYPE" = "zfs" ] ||
24147                 skip_env "the test only applies to zfs"
24148
24149         local max_blksz=$(do_facet ost1 \
24150                           $ZFS get -p recordsize $(facet_device ost1) |
24151                           awk '!/VALUE/{print $3}')
24152
24153         # to make life a little bit easier
24154         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24155         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24156
24157         local tf=$DIR/$tdir/$tfile
24158         touch $tf
24159         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24160
24161         # Get ZFS object id
24162         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24163         # block size change by sequential overwrite
24164         local bs
24165
24166         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24167                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24168
24169                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24170                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24171         done
24172         rm -f $tf
24173
24174         # block size change by sequential append write
24175         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24176         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24177         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24178         local count
24179
24180         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24181                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24182                         oflag=sync conv=notrunc
24183
24184                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24185                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24186                         error "blksz error, actual $blksz, " \
24187                                 "expected: 2 * $count * $PAGE_SIZE"
24188         done
24189         rm -f $tf
24190
24191         # random write
24192         touch $tf
24193         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24194         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24195
24196         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24197         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24198         [ $blksz -eq $PAGE_SIZE ] ||
24199                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24200
24201         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24202         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24203         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24204
24205         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24206         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24207         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24208 }
24209 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24210
24211 test_313() {
24212         remote_ost_nodsh && skip "remote OST with nodsh"
24213
24214         local file=$DIR/$tfile
24215
24216         rm -f $file
24217         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24218
24219         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24220         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24221         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24222                 error "write should failed"
24223         do_facet ost1 "$LCTL set_param fail_loc=0"
24224         rm -f $file
24225 }
24226 run_test 313 "io should fail after last_rcvd update fail"
24227
24228 test_314() {
24229         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24230
24231         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24232         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24233         rm -f $DIR/$tfile
24234         wait_delete_completed
24235         do_facet ost1 "$LCTL set_param fail_loc=0"
24236 }
24237 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24238
24239 test_315() { # LU-618
24240         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24241
24242         local file=$DIR/$tfile
24243         rm -f $file
24244
24245         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24246                 error "multiop file write failed"
24247         $MULTIOP $file oO_RDONLY:r4063232_c &
24248         PID=$!
24249
24250         sleep 2
24251
24252         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24253         kill -USR1 $PID
24254
24255         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24256         rm -f $file
24257 }
24258 run_test 315 "read should be accounted"
24259
24260 test_316() {
24261         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24262         large_xattr_enabled || skip "ea_inode feature disabled"
24263
24264         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24265         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24266         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24267         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24268
24269         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24270 }
24271 run_test 316 "lfs migrate of file with large_xattr enabled"
24272
24273 test_317() {
24274         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24275                 skip "Need MDS version at least 2.11.53"
24276         if [ "$ost1_FSTYPE" == "zfs" ]; then
24277                 skip "LU-10370: no implementation for ZFS"
24278         fi
24279
24280         local trunc_sz
24281         local grant_blk_size
24282
24283         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24284                         awk '/grant_block_size:/ { print $2; exit; }')
24285         #
24286         # Create File of size 5M. Truncate it to below size's and verify
24287         # blocks count.
24288         #
24289         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24290                 error "Create file $DIR/$tfile failed"
24291         stack_trap "rm -f $DIR/$tfile" EXIT
24292
24293         for trunc_sz in 2097152 4097 4000 509 0; do
24294                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24295                         error "truncate $tfile to $trunc_sz failed"
24296                 local sz=$(stat --format=%s $DIR/$tfile)
24297                 local blk=$(stat --format=%b $DIR/$tfile)
24298                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24299                                      grant_blk_size) * 8))
24300
24301                 if [[ $blk -ne $trunc_blk ]]; then
24302                         $(which stat) $DIR/$tfile
24303                         error "Expected Block $trunc_blk got $blk for $tfile"
24304                 fi
24305
24306                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24307                         error "Expected Size $trunc_sz got $sz for $tfile"
24308         done
24309
24310         #
24311         # sparse file test
24312         # Create file with a hole and write actual 65536 bytes which aligned
24313         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24314         #
24315         local bs=65536
24316         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24317                 error "Create file : $DIR/$tfile"
24318
24319         #
24320         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24321         # blocks. The block count must drop to 8.
24322         #
24323         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24324                 ((bs - grant_blk_size) + 1)))
24325         $TRUNCATE $DIR/$tfile $trunc_sz ||
24326                 error "truncate $tfile to $trunc_sz failed"
24327
24328         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24329         sz=$(stat --format=%s $DIR/$tfile)
24330         blk=$(stat --format=%b $DIR/$tfile)
24331
24332         if [[ $blk -ne $trunc_bsz ]]; then
24333                 $(which stat) $DIR/$tfile
24334                 error "Expected Block $trunc_bsz got $blk for $tfile"
24335         fi
24336
24337         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24338                 error "Expected Size $trunc_sz got $sz for $tfile"
24339 }
24340 run_test 317 "Verify blocks get correctly update after truncate"
24341
24342 test_318() {
24343         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24344         local old_max_active=$($LCTL get_param -n \
24345                             ${llite_name}.max_read_ahead_async_active \
24346                             2>/dev/null)
24347
24348         $LCTL set_param llite.*.max_read_ahead_async_active=256
24349         local max_active=$($LCTL get_param -n \
24350                            ${llite_name}.max_read_ahead_async_active \
24351                            2>/dev/null)
24352         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24353
24354         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24355                 error "set max_read_ahead_async_active should succeed"
24356
24357         $LCTL set_param llite.*.max_read_ahead_async_active=512
24358         max_active=$($LCTL get_param -n \
24359                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24360         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24361
24362         # restore @max_active
24363         [ $old_max_active -ne 0 ] && $LCTL set_param \
24364                 llite.*.max_read_ahead_async_active=$old_max_active
24365
24366         local old_threshold=$($LCTL get_param -n \
24367                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24368         local max_per_file_mb=$($LCTL get_param -n \
24369                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24370
24371         local invalid=$(($max_per_file_mb + 1))
24372         $LCTL set_param \
24373                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24374                         && error "set $invalid should fail"
24375
24376         local valid=$(($invalid - 1))
24377         $LCTL set_param \
24378                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24379                         error "set $valid should succeed"
24380         local threshold=$($LCTL get_param -n \
24381                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24382         [ $threshold -eq $valid ] || error \
24383                 "expect threshold $valid got $threshold"
24384         $LCTL set_param \
24385                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24386 }
24387 run_test 318 "Verify async readahead tunables"
24388
24389 test_319() {
24390         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24391
24392         local before=$(date +%s)
24393         local evict
24394         local mdir=$DIR/$tdir
24395         local file=$mdir/xxx
24396
24397         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24398         touch $file
24399
24400 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24401         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24402         $LFS migrate -m1 $mdir &
24403
24404         sleep 1
24405         dd if=$file of=/dev/null
24406         wait
24407         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24408           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24409
24410         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24411 }
24412 run_test 319 "lost lease lock on migrate error"
24413
24414 test_398a() { # LU-4198
24415         local ost1_imp=$(get_osc_import_name client ost1)
24416         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24417                          cut -d'.' -f2)
24418
24419         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24420         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24421
24422         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24423         # request a new lock on client
24424         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24425
24426         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24427         #local lock_count=$($LCTL get_param -n \
24428         #                  ldlm.namespaces.$imp_name.lru_size)
24429         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24430
24431         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24432
24433         # no lock cached, should use lockless DIO and not enqueue new lock
24434         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24435                 conv=notrunc ||
24436                 error "dio write failed"
24437         lock_count=$($LCTL get_param -n \
24438                      ldlm.namespaces.$imp_name.lru_size)
24439         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24440
24441         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24442
24443         # no lock cached, should use locked DIO append
24444         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24445                 conv=notrunc || error "DIO append failed"
24446         lock_count=$($LCTL get_param -n \
24447                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24448         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24449 }
24450 run_test 398a "direct IO should cancel lock otherwise lockless"
24451
24452 test_398b() { # LU-4198
24453         which fio || skip_env "no fio installed"
24454         $LFS setstripe -c -1 -S 1M $DIR/$tfile
24455
24456         local size=48
24457         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24458
24459         local njobs=4
24460         # Single page, multiple pages, stripe size, 4*stripe size
24461         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
24462                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
24463                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
24464                         --numjobs=$njobs --fallocate=none \
24465                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24466                         --filename=$DIR/$tfile &
24467                 bg_pid=$!
24468
24469                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
24470                 fio --name=rand-rw --rw=randrw --bs=$bsize \
24471                         --numjobs=$njobs --fallocate=none \
24472                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24473                         --filename=$DIR/$tfile || true
24474                 wait $bg_pid
24475         done
24476
24477         evict=$(do_facet client $LCTL get_param \
24478                 osc.$FSNAME-OST*-osc-*/state |
24479             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
24480
24481         [ -z "$evict" ] || [[ $evict -le $before ]] ||
24482                 (do_facet client $LCTL get_param \
24483                         osc.$FSNAME-OST*-osc-*/state;
24484                     error "eviction happened: $evict before:$before")
24485
24486         rm -f $DIR/$tfile
24487 }
24488 run_test 398b "DIO and buffer IO race"
24489
24490 test_398c() { # LU-4198
24491         local ost1_imp=$(get_osc_import_name client ost1)
24492         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24493                          cut -d'.' -f2)
24494
24495         which fio || skip_env "no fio installed"
24496
24497         saved_debug=$($LCTL get_param -n debug)
24498         $LCTL set_param debug=0
24499
24500         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24501         ((size /= 1024)) # by megabytes
24502         ((size /= 2)) # write half of the OST at most
24503         [ $size -gt 40 ] && size=40 #reduce test time anyway
24504
24505         $LFS setstripe -c 1 $DIR/$tfile
24506
24507         # it seems like ldiskfs reserves more space than necessary if the
24508         # writing blocks are not mapped, so it extends the file firstly
24509         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24510         cancel_lru_locks osc
24511
24512         # clear and verify rpc_stats later
24513         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24514
24515         local njobs=4
24516         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24517         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24518                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24519                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24520                 --filename=$DIR/$tfile
24521         [ $? -eq 0 ] || error "fio write error"
24522
24523         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24524                 error "Locks were requested while doing AIO"
24525
24526         # get the percentage of 1-page I/O
24527         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24528                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24529                 awk '{print $7}')
24530         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24531
24532         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24533         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24534                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24535                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24536                 --filename=$DIR/$tfile
24537         [ $? -eq 0 ] || error "fio mixed read write error"
24538
24539         echo "AIO with large block size ${size}M"
24540         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24541                 --numjobs=1 --fallocate=none --ioengine=libaio \
24542                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24543                 --filename=$DIR/$tfile
24544         [ $? -eq 0 ] || error "fio large block size failed"
24545
24546         rm -f $DIR/$tfile
24547         $LCTL set_param debug="$saved_debug"
24548 }
24549 run_test 398c "run fio to test AIO"
24550
24551 test_398d() { #  LU-13846
24552         which aiocp || skip_env "no aiocp installed"
24553         local aio_file=$DIR/$tfile.aio
24554
24555         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24556
24557         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24558         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24559         stack_trap "rm -f $DIR/$tfile $aio_file"
24560
24561         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24562
24563         # make sure we don't crash and fail properly
24564         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24565                 error "aio not aligned with PAGE SIZE should fail"
24566
24567         rm -f $DIR/$tfile $aio_file
24568 }
24569 run_test 398d "run aiocp to verify block size > stripe size"
24570
24571 test_398e() {
24572         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24573         touch $DIR/$tfile.new
24574         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24575 }
24576 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24577
24578 test_398f() { #  LU-14687
24579         which aiocp || skip_env "no aiocp installed"
24580         local aio_file=$DIR/$tfile.aio
24581
24582         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24583
24584         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24585         stack_trap "rm -f $DIR/$tfile $aio_file"
24586
24587         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24588         $LCTL set_param fail_loc=0x1418
24589         # make sure we don't crash and fail properly
24590         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24591                 error "aio with page allocation failure succeeded"
24592         $LCTL set_param fail_loc=0
24593         diff $DIR/$tfile $aio_file
24594         [[ $? != 0 ]] || error "no diff after failed aiocp"
24595 }
24596 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24597
24598 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24599 # stripe and i/o size must be > stripe size
24600 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24601 # single RPC in flight.  This test shows async DIO submission is working by
24602 # showing multiple RPCs in flight.
24603 test_398g() { #  LU-13798
24604         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24605
24606         # We need to do some i/o first to acquire enough grant to put our RPCs
24607         # in flight; otherwise a new connection may not have enough grant
24608         # available
24609         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24610                 error "parallel dio failed"
24611         stack_trap "rm -f $DIR/$tfile"
24612
24613         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24614         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24615         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24616         stack_trap "$LCTL set_param -n $pages_per_rpc"
24617
24618         # Recreate file so it's empty
24619         rm -f $DIR/$tfile
24620         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24621         #Pause rpc completion to guarantee we see multiple rpcs in flight
24622         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24623         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24624         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24625
24626         # Clear rpc stats
24627         $LCTL set_param osc.*.rpc_stats=c
24628
24629         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24630                 error "parallel dio failed"
24631         stack_trap "rm -f $DIR/$tfile"
24632
24633         $LCTL get_param osc.*-OST0000-*.rpc_stats
24634         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24635                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24636                 grep "8:" | awk '{print $8}')
24637         # We look at the "8 rpcs in flight" field, and verify A) it is present
24638         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24639         # as expected for an 8M DIO to a file with 1M stripes.
24640         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24641
24642         # Verify turning off parallel dio works as expected
24643         # Clear rpc stats
24644         $LCTL set_param osc.*.rpc_stats=c
24645         $LCTL set_param llite.*.parallel_dio=0
24646         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24647
24648         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24649                 error "dio with parallel dio disabled failed"
24650
24651         # Ideally, we would see only one RPC in flight here, but there is an
24652         # unavoidable race between i/o completion and RPC in flight counting,
24653         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24654         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24655         # So instead we just verify it's always < 8.
24656         $LCTL get_param osc.*-OST0000-*.rpc_stats
24657         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24658                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24659                 grep '^$' -B1 | grep . | awk '{print $1}')
24660         [ $ret != "8:" ] ||
24661                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24662 }
24663 run_test 398g "verify parallel dio async RPC submission"
24664
24665 test_398h() { #  LU-13798
24666         local dio_file=$DIR/$tfile.dio
24667
24668         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24669
24670         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24671         stack_trap "rm -f $DIR/$tfile $dio_file"
24672
24673         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24674                 error "parallel dio failed"
24675         diff $DIR/$tfile $dio_file
24676         [[ $? == 0 ]] || error "file diff after aiocp"
24677 }
24678 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24679
24680 test_398i() { #  LU-13798
24681         local dio_file=$DIR/$tfile.dio
24682
24683         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24684
24685         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24686         stack_trap "rm -f $DIR/$tfile $dio_file"
24687
24688         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24689         $LCTL set_param fail_loc=0x1418
24690         # make sure we don't crash and fail properly
24691         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24692                 error "parallel dio page allocation failure succeeded"
24693         diff $DIR/$tfile $dio_file
24694         [[ $? != 0 ]] || error "no diff after failed aiocp"
24695 }
24696 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24697
24698 test_398j() { #  LU-13798
24699         # Stripe size > RPC size but less than i/o size tests split across
24700         # stripes and RPCs for individual i/o op
24701         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24702
24703         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24704         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24705         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24706         stack_trap "$LCTL set_param -n $pages_per_rpc"
24707
24708         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24709                 error "parallel dio write failed"
24710         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24711
24712         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24713                 error "parallel dio read failed"
24714         diff $DIR/$tfile $DIR/$tfile.2
24715         [[ $? == 0 ]] || error "file diff after parallel dio read"
24716 }
24717 run_test 398j "test parallel dio where stripe size > rpc_size"
24718
24719 test_398k() { #  LU-13798
24720         wait_delete_completed
24721         wait_mds_ost_sync
24722
24723         # 4 stripe file; we will cause out of space on OST0
24724         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24725
24726         # Fill OST0 (if it's not too large)
24727         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24728                    head -n1)
24729         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24730                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24731         fi
24732         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24733         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24734                 error "dd should fill OST0"
24735         stack_trap "rm -f $DIR/$tfile.1"
24736
24737         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24738         err=$?
24739
24740         ls -la $DIR/$tfile
24741         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24742                 error "file is not 0 bytes in size"
24743
24744         # dd above should not succeed, but don't error until here so we can
24745         # get debug info above
24746         [[ $err != 0 ]] ||
24747                 error "parallel dio write with enospc succeeded"
24748         stack_trap "rm -f $DIR/$tfile"
24749 }
24750 run_test 398k "test enospc on first stripe"
24751
24752 test_398l() { #  LU-13798
24753         wait_delete_completed
24754         wait_mds_ost_sync
24755
24756         # 4 stripe file; we will cause out of space on OST0
24757         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24758         # happens on the second i/o chunk we issue
24759         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24760
24761         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24762         stack_trap "rm -f $DIR/$tfile"
24763
24764         # Fill OST0 (if it's not too large)
24765         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24766                    head -n1)
24767         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24768                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24769         fi
24770         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24771         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24772                 error "dd should fill OST0"
24773         stack_trap "rm -f $DIR/$tfile.1"
24774
24775         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24776         err=$?
24777         stack_trap "rm -f $DIR/$tfile.2"
24778
24779         # Check that short write completed as expected
24780         ls -la $DIR/$tfile.2
24781         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24782                 error "file is not 1M in size"
24783
24784         # dd above should not succeed, but don't error until here so we can
24785         # get debug info above
24786         [[ $err != 0 ]] ||
24787                 error "parallel dio write with enospc succeeded"
24788
24789         # Truncate source file to same length as output file and diff them
24790         $TRUNCATE $DIR/$tfile 1048576
24791         diff $DIR/$tfile $DIR/$tfile.2
24792         [[ $? == 0 ]] || error "data incorrect after short write"
24793 }
24794 run_test 398l "test enospc on intermediate stripe/RPC"
24795
24796 test_398m() { #  LU-13798
24797         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24798
24799         # Set up failure on OST0, the first stripe:
24800         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24801         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24802         # So this fail_val specifies OST0
24803         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24804         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24805
24806         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24807                 error "parallel dio write with failure on first stripe succeeded"
24808         stack_trap "rm -f $DIR/$tfile"
24809         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24810
24811         # Place data in file for read
24812         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24813                 error "parallel dio write failed"
24814
24815         # Fail read on OST0, first stripe
24816         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24817         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24818         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24819                 error "parallel dio read with error on first stripe succeeded"
24820         rm -f $DIR/$tfile.2
24821         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24822
24823         # Switch to testing on OST1, second stripe
24824         # Clear file contents, maintain striping
24825         echo > $DIR/$tfile
24826         # Set up failure on OST1, second stripe:
24827         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24828         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24829
24830         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24831                 error "parallel dio write with failure on first stripe succeeded"
24832         stack_trap "rm -f $DIR/$tfile"
24833         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24834
24835         # Place data in file for read
24836         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24837                 error "parallel dio write failed"
24838
24839         # Fail read on OST1, second stripe
24840         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24841         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24842         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24843                 error "parallel dio read with error on first stripe succeeded"
24844         rm -f $DIR/$tfile.2
24845         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24846 }
24847 run_test 398m "test RPC failures with parallel dio"
24848
24849 # Parallel submission of DIO should not cause problems for append, but it's
24850 # important to verify.
24851 test_398n() { #  LU-13798
24852         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24853
24854         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24855                 error "dd to create source file failed"
24856         stack_trap "rm -f $DIR/$tfile"
24857
24858         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24859                 error "parallel dio write with failure on second stripe succeeded"
24860         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24861         diff $DIR/$tfile $DIR/$tfile.1
24862         [[ $? == 0 ]] || error "data incorrect after append"
24863
24864 }
24865 run_test 398n "test append with parallel DIO"
24866
24867 test_fake_rw() {
24868         local read_write=$1
24869         if [ "$read_write" = "write" ]; then
24870                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24871         elif [ "$read_write" = "read" ]; then
24872                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24873         else
24874                 error "argument error"
24875         fi
24876
24877         # turn off debug for performance testing
24878         local saved_debug=$($LCTL get_param -n debug)
24879         $LCTL set_param debug=0
24880
24881         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24882
24883         # get ost1 size - $FSNAME-OST0000
24884         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24885         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24886         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24887
24888         if [ "$read_write" = "read" ]; then
24889                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24890         fi
24891
24892         local start_time=$(date +%s.%N)
24893         $dd_cmd bs=1M count=$blocks oflag=sync ||
24894                 error "real dd $read_write error"
24895         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24896
24897         if [ "$read_write" = "write" ]; then
24898                 rm -f $DIR/$tfile
24899         fi
24900
24901         # define OBD_FAIL_OST_FAKE_RW           0x238
24902         do_facet ost1 $LCTL set_param fail_loc=0x238
24903
24904         local start_time=$(date +%s.%N)
24905         $dd_cmd bs=1M count=$blocks oflag=sync ||
24906                 error "fake dd $read_write error"
24907         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24908
24909         if [ "$read_write" = "write" ]; then
24910                 # verify file size
24911                 cancel_lru_locks osc
24912                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24913                         error "$tfile size not $blocks MB"
24914         fi
24915         do_facet ost1 $LCTL set_param fail_loc=0
24916
24917         echo "fake $read_write $duration_fake vs. normal $read_write" \
24918                 "$duration in seconds"
24919         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24920                 error_not_in_vm "fake write is slower"
24921
24922         $LCTL set_param -n debug="$saved_debug"
24923         rm -f $DIR/$tfile
24924 }
24925 test_399a() { # LU-7655 for OST fake write
24926         remote_ost_nodsh && skip "remote OST with nodsh"
24927
24928         test_fake_rw write
24929 }
24930 run_test 399a "fake write should not be slower than normal write"
24931
24932 test_399b() { # LU-8726 for OST fake read
24933         remote_ost_nodsh && skip "remote OST with nodsh"
24934         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24935                 skip_env "ldiskfs only test"
24936         fi
24937
24938         test_fake_rw read
24939 }
24940 run_test 399b "fake read should not be slower than normal read"
24941
24942 test_400a() { # LU-1606, was conf-sanity test_74
24943         if ! which $CC > /dev/null 2>&1; then
24944                 skip_env "$CC is not installed"
24945         fi
24946
24947         local extra_flags=''
24948         local out=$TMP/$tfile
24949         local prefix=/usr/include/lustre
24950         local prog
24951
24952         # Oleg removes c files in his test rig so test if any c files exist
24953         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24954                 skip_env "Needed c test files are missing"
24955
24956         if ! [[ -d $prefix ]]; then
24957                 # Assume we're running in tree and fixup the include path.
24958                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24959                 extra_flags+=" -L$LUSTRE/utils/.lib"
24960         fi
24961
24962         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24963                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24964                         error "client api broken"
24965         done
24966         rm -f $out
24967 }
24968 run_test 400a "Lustre client api program can compile and link"
24969
24970 test_400b() { # LU-1606, LU-5011
24971         local header
24972         local out=$TMP/$tfile
24973         local prefix=/usr/include/linux/lustre
24974
24975         # We use a hard coded prefix so that this test will not fail
24976         # when run in tree. There are headers in lustre/include/lustre/
24977         # that are not packaged (like lustre_idl.h) and have more
24978         # complicated include dependencies (like config.h and lnet/types.h).
24979         # Since this test about correct packaging we just skip them when
24980         # they don't exist (see below) rather than try to fixup cppflags.
24981
24982         if ! which $CC > /dev/null 2>&1; then
24983                 skip_env "$CC is not installed"
24984         fi
24985
24986         for header in $prefix/*.h; do
24987                 if ! [[ -f "$header" ]]; then
24988                         continue
24989                 fi
24990
24991                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24992                         continue # lustre_ioctl.h is internal header
24993                 fi
24994
24995                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24996                         error "cannot compile '$header'"
24997         done
24998         rm -f $out
24999 }
25000 run_test 400b "packaged headers can be compiled"
25001
25002 test_401a() { #LU-7437
25003         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25004         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25005
25006         #count the number of parameters by "list_param -R"
25007         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25008         #count the number of parameters by listing proc files
25009         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25010         echo "proc_dirs='$proc_dirs'"
25011         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25012         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25013                       sort -u | wc -l)
25014
25015         [ $params -eq $procs ] ||
25016                 error "found $params parameters vs. $procs proc files"
25017
25018         # test the list_param -D option only returns directories
25019         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25020         #count the number of parameters by listing proc directories
25021         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25022                 sort -u | wc -l)
25023
25024         [ $params -eq $procs ] ||
25025                 error "found $params parameters vs. $procs proc files"
25026 }
25027 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25028
25029 test_401b() {
25030         # jobid_var may not allow arbitrary values, so use jobid_name
25031         # if available
25032         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25033                 local testname=jobid_name tmp='testing%p'
25034         else
25035                 local testname=jobid_var tmp=testing
25036         fi
25037
25038         local save=$($LCTL get_param -n $testname)
25039
25040         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25041                 error "no error returned when setting bad parameters"
25042
25043         local jobid_new=$($LCTL get_param -n foe $testname baz)
25044         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25045
25046         $LCTL set_param -n fog=bam $testname=$save bat=fog
25047         local jobid_old=$($LCTL get_param -n foe $testname bag)
25048         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25049 }
25050 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25051
25052 test_401c() {
25053         # jobid_var may not allow arbitrary values, so use jobid_name
25054         # if available
25055         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25056                 local testname=jobid_name
25057         else
25058                 local testname=jobid_var
25059         fi
25060
25061         local jobid_var_old=$($LCTL get_param -n $testname)
25062         local jobid_var_new
25063
25064         $LCTL set_param $testname= &&
25065                 error "no error returned for 'set_param a='"
25066
25067         jobid_var_new=$($LCTL get_param -n $testname)
25068         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25069                 error "$testname was changed by setting without value"
25070
25071         $LCTL set_param $testname &&
25072                 error "no error returned for 'set_param a'"
25073
25074         jobid_var_new=$($LCTL get_param -n $testname)
25075         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25076                 error "$testname was changed by setting without value"
25077 }
25078 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25079
25080 test_401d() {
25081         # jobid_var may not allow arbitrary values, so use jobid_name
25082         # if available
25083         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25084                 local testname=jobid_name new_value='foo=bar%p'
25085         else
25086                 local testname=jobid_var new_valuie=foo=bar
25087         fi
25088
25089         local jobid_var_old=$($LCTL get_param -n $testname)
25090         local jobid_var_new
25091
25092         $LCTL set_param $testname=$new_value ||
25093                 error "'set_param a=b' did not accept a value containing '='"
25094
25095         jobid_var_new=$($LCTL get_param -n $testname)
25096         [[ "$jobid_var_new" == "$new_value" ]] ||
25097                 error "'set_param a=b' failed on a value containing '='"
25098
25099         # Reset the $testname to test the other format
25100         $LCTL set_param $testname=$jobid_var_old
25101         jobid_var_new=$($LCTL get_param -n $testname)
25102         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25103                 error "failed to reset $testname"
25104
25105         $LCTL set_param $testname $new_value ||
25106                 error "'set_param a b' did not accept a value containing '='"
25107
25108         jobid_var_new=$($LCTL get_param -n $testname)
25109         [[ "$jobid_var_new" == "$new_value" ]] ||
25110                 error "'set_param a b' failed on a value containing '='"
25111
25112         $LCTL set_param $testname $jobid_var_old
25113         jobid_var_new=$($LCTL get_param -n $testname)
25114         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25115                 error "failed to reset $testname"
25116 }
25117 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25118
25119 test_401e() { # LU-14779
25120         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25121                 error "lctl list_param MGC* failed"
25122         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25123         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25124                 error "lctl get_param lru_size failed"
25125 }
25126 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25127
25128 test_402() {
25129         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25130         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25131                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25132         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25133                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25134                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25135         remote_mds_nodsh && skip "remote MDS with nodsh"
25136
25137         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25138 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25139         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25140         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25141                 echo "Touch failed - OK"
25142 }
25143 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25144
25145 test_403() {
25146         local file1=$DIR/$tfile.1
25147         local file2=$DIR/$tfile.2
25148         local tfile=$TMP/$tfile
25149
25150         rm -f $file1 $file2 $tfile
25151
25152         touch $file1
25153         ln $file1 $file2
25154
25155         # 30 sec OBD_TIMEOUT in ll_getattr()
25156         # right before populating st_nlink
25157         $LCTL set_param fail_loc=0x80001409
25158         stat -c %h $file1 > $tfile &
25159
25160         # create an alias, drop all locks and reclaim the dentry
25161         < $file2
25162         cancel_lru_locks mdc
25163         cancel_lru_locks osc
25164         sysctl -w vm.drop_caches=2
25165
25166         wait
25167
25168         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25169
25170         rm -f $tfile $file1 $file2
25171 }
25172 run_test 403 "i_nlink should not drop to zero due to aliasing"
25173
25174 test_404() { # LU-6601
25175         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25176                 skip "Need server version newer than 2.8.52"
25177         remote_mds_nodsh && skip "remote MDS with nodsh"
25178
25179         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25180                 awk '/osp .*-osc-MDT/ { print $4}')
25181
25182         local osp
25183         for osp in $mosps; do
25184                 echo "Deactivate: " $osp
25185                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25186                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25187                         awk -vp=$osp '$4 == p { print $2 }')
25188                 [ $stat = IN ] || {
25189                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25190                         error "deactivate error"
25191                 }
25192                 echo "Activate: " $osp
25193                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25194                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25195                         awk -vp=$osp '$4 == p { print $2 }')
25196                 [ $stat = UP ] || {
25197                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25198                         error "activate error"
25199                 }
25200         done
25201 }
25202 run_test 404 "validate manual {de}activated works properly for OSPs"
25203
25204 test_405() {
25205         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25206         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25207                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25208                         skip "Layout swap lock is not supported"
25209
25210         check_swap_layouts_support
25211         check_swap_layout_no_dom $DIR
25212
25213         test_mkdir $DIR/$tdir
25214         swap_lock_test -d $DIR/$tdir ||
25215                 error "One layout swap locked test failed"
25216 }
25217 run_test 405 "Various layout swap lock tests"
25218
25219 test_406() {
25220         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25221         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25222         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25224         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25225                 skip "Need MDS version at least 2.8.50"
25226
25227         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25228         local test_pool=$TESTNAME
25229
25230         pool_add $test_pool || error "pool_add failed"
25231         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25232                 error "pool_add_targets failed"
25233
25234         save_layout_restore_at_exit $MOUNT
25235
25236         # parent set default stripe count only, child will stripe from both
25237         # parent and fs default
25238         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25239                 error "setstripe $MOUNT failed"
25240         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25241         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25242         for i in $(seq 10); do
25243                 local f=$DIR/$tdir/$tfile.$i
25244                 touch $f || error "touch failed"
25245                 local count=$($LFS getstripe -c $f)
25246                 [ $count -eq $OSTCOUNT ] ||
25247                         error "$f stripe count $count != $OSTCOUNT"
25248                 local offset=$($LFS getstripe -i $f)
25249                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25250                 local size=$($LFS getstripe -S $f)
25251                 [ $size -eq $((def_stripe_size * 2)) ] ||
25252                         error "$f stripe size $size != $((def_stripe_size * 2))"
25253                 local pool=$($LFS getstripe -p $f)
25254                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25255         done
25256
25257         # change fs default striping, delete parent default striping, now child
25258         # will stripe from new fs default striping only
25259         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25260                 error "change $MOUNT default stripe failed"
25261         $LFS setstripe -c 0 $DIR/$tdir ||
25262                 error "delete $tdir default stripe failed"
25263         for i in $(seq 11 20); do
25264                 local f=$DIR/$tdir/$tfile.$i
25265                 touch $f || error "touch $f failed"
25266                 local count=$($LFS getstripe -c $f)
25267                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25268                 local offset=$($LFS getstripe -i $f)
25269                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25270                 local size=$($LFS getstripe -S $f)
25271                 [ $size -eq $def_stripe_size ] ||
25272                         error "$f stripe size $size != $def_stripe_size"
25273                 local pool=$($LFS getstripe -p $f)
25274                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25275         done
25276
25277         unlinkmany $DIR/$tdir/$tfile. 1 20
25278
25279         local f=$DIR/$tdir/$tfile
25280         pool_remove_all_targets $test_pool $f
25281         pool_remove $test_pool $f
25282 }
25283 run_test 406 "DNE support fs default striping"
25284
25285 test_407() {
25286         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25287         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25288                 skip "Need MDS version at least 2.8.55"
25289         remote_mds_nodsh && skip "remote MDS with nodsh"
25290
25291         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25292                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25293         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25294                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25295         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25296
25297         #define OBD_FAIL_DT_TXN_STOP    0x2019
25298         for idx in $(seq $MDSCOUNT); do
25299                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25300         done
25301         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25302         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25303                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25304         true
25305 }
25306 run_test 407 "transaction fail should cause operation fail"
25307
25308 test_408() {
25309         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25310
25311         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25312         lctl set_param fail_loc=0x8000040a
25313         # let ll_prepare_partial_page() fail
25314         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25315
25316         rm -f $DIR/$tfile
25317
25318         # create at least 100 unused inodes so that
25319         # shrink_icache_memory(0) should not return 0
25320         touch $DIR/$tfile-{0..100}
25321         rm -f $DIR/$tfile-{0..100}
25322         sync
25323
25324         echo 2 > /proc/sys/vm/drop_caches
25325 }
25326 run_test 408 "drop_caches should not hang due to page leaks"
25327
25328 test_409()
25329 {
25330         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25331
25332         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25333         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25334         touch $DIR/$tdir/guard || error "(2) Fail to create"
25335
25336         local PREFIX=$(str_repeat 'A' 128)
25337         echo "Create 1K hard links start at $(date)"
25338         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25339                 error "(3) Fail to hard link"
25340
25341         echo "Links count should be right although linkEA overflow"
25342         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25343         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25344         [ $linkcount -eq 1001 ] ||
25345                 error "(5) Unexpected hard links count: $linkcount"
25346
25347         echo "List all links start at $(date)"
25348         ls -l $DIR/$tdir/foo > /dev/null ||
25349                 error "(6) Fail to list $DIR/$tdir/foo"
25350
25351         echo "Unlink hard links start at $(date)"
25352         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25353                 error "(7) Fail to unlink"
25354         echo "Unlink hard links finished at $(date)"
25355 }
25356 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25357
25358 test_410()
25359 {
25360         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25361                 skip "Need client version at least 2.9.59"
25362         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25363                 skip "Need MODULES build"
25364
25365         # Create a file, and stat it from the kernel
25366         local testfile=$DIR/$tfile
25367         touch $testfile
25368
25369         local run_id=$RANDOM
25370         local my_ino=$(stat --format "%i" $testfile)
25371
25372         # Try to insert the module. This will always fail as the
25373         # module is designed to not be inserted.
25374         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25375             &> /dev/null
25376
25377         # Anything but success is a test failure
25378         dmesg | grep -q \
25379             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25380             error "no inode match"
25381 }
25382 run_test 410 "Test inode number returned from kernel thread"
25383
25384 cleanup_test411_cgroup() {
25385         trap 0
25386         rmdir "$1"
25387 }
25388
25389 test_411() {
25390         local cg_basedir=/sys/fs/cgroup/memory
25391         # LU-9966
25392         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25393                 skip "no setup for cgroup"
25394
25395         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25396                 error "test file creation failed"
25397         cancel_lru_locks osc
25398
25399         # Create a very small memory cgroup to force a slab allocation error
25400         local cgdir=$cg_basedir/osc_slab_alloc
25401         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25402         trap "cleanup_test411_cgroup $cgdir" EXIT
25403         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25404         echo 1M > $cgdir/memory.limit_in_bytes
25405
25406         # Should not LBUG, just be killed by oom-killer
25407         # dd will return 0 even allocation failure in some environment.
25408         # So don't check return value
25409         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25410         cleanup_test411_cgroup $cgdir
25411
25412         return 0
25413 }
25414 run_test 411 "Slab allocation error with cgroup does not LBUG"
25415
25416 test_412() {
25417         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25418         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25419                 skip "Need server version at least 2.10.55"
25420
25421         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25422                 error "mkdir failed"
25423         $LFS getdirstripe $DIR/$tdir
25424         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25425         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25426                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25427         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25428         [ $stripe_count -eq 2 ] ||
25429                 error "expect 2 get $stripe_count"
25430
25431         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25432
25433         local index
25434         local index2
25435
25436         # subdirs should be on the same MDT as parent
25437         for i in $(seq 0 $((MDSCOUNT - 1))); do
25438                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25439                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25440                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25441                 (( index == i )) || error "mdt$i/sub on MDT$index"
25442         done
25443
25444         # stripe offset -1, ditto
25445         for i in {1..10}; do
25446                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25447                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25448                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25449                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25450                 (( index == index2 )) ||
25451                         error "qos$i on MDT$index, sub on MDT$index2"
25452         done
25453
25454         local testdir=$DIR/$tdir/inherit
25455
25456         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25457         # inherit 2 levels
25458         for i in 1 2; do
25459                 testdir=$testdir/s$i
25460                 mkdir $testdir || error "mkdir $testdir failed"
25461                 index=$($LFS getstripe -m $testdir)
25462                 (( index == 1 )) ||
25463                         error "$testdir on MDT$index"
25464         done
25465
25466         # not inherit any more
25467         testdir=$testdir/s3
25468         mkdir $testdir || error "mkdir $testdir failed"
25469         getfattr -d -m dmv $testdir | grep dmv &&
25470                 error "default LMV set on $testdir" || true
25471 }
25472 run_test 412 "mkdir on specific MDTs"
25473
25474 generate_uneven_mdts() {
25475         local threshold=$1
25476         local lmv_qos_maxage
25477         local lod_qos_maxage
25478         local ffree
25479         local bavail
25480         local max
25481         local min
25482         local max_index
25483         local min_index
25484         local tmp
25485         local i
25486
25487         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25488         $LCTL set_param lmv.*.qos_maxage=1
25489         stack_trap "$LCTL set_param \
25490                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25491         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25492                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25493         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25494                 lod.*.mdt_qos_maxage=1
25495         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25496                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25497
25498         echo
25499         echo "Check for uneven MDTs: "
25500
25501         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25502         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25503         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25504
25505         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25506         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25507         max_index=0
25508         min_index=0
25509         for ((i = 1; i < ${#ffree[@]}; i++)); do
25510                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25511                 if [ $tmp -gt $max ]; then
25512                         max=$tmp
25513                         max_index=$i
25514                 fi
25515                 if [ $tmp -lt $min ]; then
25516                         min=$tmp
25517                         min_index=$i
25518                 fi
25519         done
25520
25521         (( ${ffree[min_index]} > 0 )) ||
25522                 skip "no free files in MDT$min_index"
25523         (( ${ffree[min_index]} < 10000000 )) ||
25524                 skip "too many free files in MDT$min_index"
25525
25526         # Check if we need to generate uneven MDTs
25527         local diff=$(((max - min) * 100 / min))
25528         local testdir=$DIR/$tdir-fillmdt
25529         local start
25530
25531         mkdir -p $testdir
25532
25533         i=0
25534         while (( diff < threshold )); do
25535                 # generate uneven MDTs, create till $threshold% diff
25536                 echo -n "weight diff=$diff% must be > $threshold% ..."
25537                 echo "Fill MDT$min_index with 1000 files: loop $i"
25538                 testdir=$DIR/$tdir-fillmdt/$i
25539                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25540                         error "mkdir $testdir failed"
25541                 $LFS setstripe -E 1M -L mdt $testdir ||
25542                         error "setstripe $testdir failed"
25543                 start=$SECONDS
25544                 for F in f.{0..999}; do
25545                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25546                                 /dev/null 2>&1 || error "dd $F failed"
25547                 done
25548
25549                 # wait for QOS to update
25550                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25551
25552                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25553                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25554                 max=$(((${ffree[max_index]} >> 8) *
25555                         (${bavail[max_index]} * bsize >> 16)))
25556                 min=$(((${ffree[min_index]} >> 8) *
25557                         (${bavail[min_index]} * bsize >> 16)))
25558                 diff=$(((max - min) * 100 / min))
25559                 i=$((i + 1))
25560         done
25561
25562         echo "MDT filesfree available: ${ffree[*]}"
25563         echo "MDT blocks available: ${bavail[*]}"
25564         echo "weight diff=$diff%"
25565 }
25566
25567 test_qos_mkdir() {
25568         local mkdir_cmd=$1
25569         local stripe_count=$2
25570         local mdts=$(comma_list $(mdts_nodes))
25571
25572         local testdir
25573         local lmv_qos_prio_free
25574         local lmv_qos_threshold_rr
25575         local lmv_qos_maxage
25576         local lod_qos_prio_free
25577         local lod_qos_threshold_rr
25578         local lod_qos_maxage
25579         local count
25580         local i
25581
25582         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25583         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25584         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25585                 head -n1)
25586         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25587         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25588         stack_trap "$LCTL set_param \
25589                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25590         stack_trap "$LCTL set_param \
25591                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25592         stack_trap "$LCTL set_param \
25593                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25594
25595         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25596                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25597         lod_qos_prio_free=${lod_qos_prio_free%%%}
25598         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25599                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25600         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25601         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25602                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25603         stack_trap "do_nodes $mdts $LCTL set_param \
25604                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25605         stack_trap "do_nodes $mdts $LCTL set_param \
25606                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25607         stack_trap "do_nodes $mdts $LCTL set_param \
25608                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25609
25610         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25611         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25612
25613         testdir=$DIR/$tdir-s$stripe_count/rr
25614
25615         local stripe_index=$($LFS getstripe -m $testdir)
25616         local test_mkdir_rr=true
25617
25618         getfattr -d -m dmv -e hex $testdir | grep dmv
25619         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25620                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25621                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25622                         test_mkdir_rr=false
25623         fi
25624
25625         echo
25626         $test_mkdir_rr &&
25627                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25628                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25629
25630         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25631         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25632                 eval $mkdir_cmd $testdir/subdir$i ||
25633                         error "$mkdir_cmd subdir$i failed"
25634         done
25635
25636         for (( i = 0; i < $MDSCOUNT; i++ )); do
25637                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25638                 echo "$count directories created on MDT$i"
25639                 if $test_mkdir_rr; then
25640                         (( $count == 100 )) ||
25641                                 error "subdirs are not evenly distributed"
25642                 elif (( $i == $stripe_index )); then
25643                         (( $count == 100 * MDSCOUNT )) ||
25644                                 error "$count subdirs created on MDT$i"
25645                 else
25646                         (( $count == 0 )) ||
25647                                 error "$count subdirs created on MDT$i"
25648                 fi
25649
25650                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25651                         count=$($LFS getdirstripe $testdir/* |
25652                                 grep -c -P "^\s+$i\t")
25653                         echo "$count stripes created on MDT$i"
25654                         # deviation should < 5% of average
25655                         (( $count >= 95 * stripe_count &&
25656                            $count <= 105 * stripe_count)) ||
25657                                 error "stripes are not evenly distributed"
25658                 fi
25659         done
25660
25661         echo
25662         echo "Check for uneven MDTs: "
25663
25664         local ffree
25665         local bavail
25666         local max
25667         local min
25668         local max_index
25669         local min_index
25670         local tmp
25671
25672         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25673         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25674         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25675
25676         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25677         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25678         max_index=0
25679         min_index=0
25680         for ((i = 1; i < ${#ffree[@]}; i++)); do
25681                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25682                 if [ $tmp -gt $max ]; then
25683                         max=$tmp
25684                         max_index=$i
25685                 fi
25686                 if [ $tmp -lt $min ]; then
25687                         min=$tmp
25688                         min_index=$i
25689                 fi
25690         done
25691
25692         (( ${ffree[min_index]} > 0 )) ||
25693                 skip "no free files in MDT$min_index"
25694         (( ${ffree[min_index]} < 10000000 )) ||
25695                 skip "too many free files in MDT$min_index"
25696
25697         echo "MDT filesfree available: ${ffree[*]}"
25698         echo "MDT blocks available: ${bavail[*]}"
25699         echo "weight diff=$(((max - min) * 100 / min))%"
25700         echo
25701         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25702
25703         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25704         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25705         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25706         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25707         # decrease statfs age, so that it can be updated in time
25708         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25709         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25710
25711         sleep 1
25712
25713         testdir=$DIR/$tdir-s$stripe_count/qos
25714         local num=200
25715
25716         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25717         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25718                 eval $mkdir_cmd $testdir/subdir$i ||
25719                         error "$mkdir_cmd subdir$i failed"
25720         done
25721
25722         max=0
25723         for (( i = 0; i < $MDSCOUNT; i++ )); do
25724                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25725                 (( count > max )) && max=$count
25726                 echo "$count directories created on MDT$i"
25727         done
25728
25729         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25730
25731         # D-value should > 10% of averge
25732         (( max - min > num / 10 )) ||
25733                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25734
25735         # ditto for stripes
25736         if (( stripe_count > 1 )); then
25737                 max=0
25738                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25739                         count=$($LFS getdirstripe $testdir/* |
25740                                 grep -c -P "^\s+$i\t")
25741                         (( count > max )) && max=$count
25742                         echo "$count stripes created on MDT$i"
25743                 done
25744
25745                 min=$($LFS getdirstripe $testdir/* |
25746                         grep -c -P "^\s+$min_index\t")
25747                 (( max - min > num * stripe_count / 10 )) ||
25748                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25749         fi
25750 }
25751
25752 most_full_mdt() {
25753         local ffree
25754         local bavail
25755         local bsize
25756         local min
25757         local min_index
25758         local tmp
25759
25760         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25761         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25762         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25763
25764         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25765         min_index=0
25766         for ((i = 1; i < ${#ffree[@]}; i++)); do
25767                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25768                 (( tmp < min )) && min=$tmp && min_index=$i
25769         done
25770
25771         echo -n $min_index
25772 }
25773
25774 test_413a() {
25775         [ $MDSCOUNT -lt 2 ] &&
25776                 skip "We need at least 2 MDTs for this test"
25777
25778         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25779                 skip "Need server version at least 2.12.52"
25780
25781         local stripe_count
25782
25783         generate_uneven_mdts 100
25784         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25785                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25786                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25787                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25788                         error "mkdir failed"
25789                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25790         done
25791 }
25792 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25793
25794 test_413b() {
25795         [ $MDSCOUNT -lt 2 ] &&
25796                 skip "We need at least 2 MDTs for this test"
25797
25798         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25799                 skip "Need server version at least 2.12.52"
25800
25801         local testdir
25802         local stripe_count
25803
25804         generate_uneven_mdts 100
25805         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25806                 testdir=$DIR/$tdir-s$stripe_count
25807                 mkdir $testdir || error "mkdir $testdir failed"
25808                 mkdir $testdir/rr || error "mkdir rr failed"
25809                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25810                         error "mkdir qos failed"
25811                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25812                         $testdir/rr || error "setdirstripe rr failed"
25813                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25814                         error "setdirstripe failed"
25815                 test_qos_mkdir "mkdir" $stripe_count
25816         done
25817 }
25818 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25819
25820 test_413c() {
25821         (( $MDSCOUNT >= 2 )) ||
25822                 skip "We need at least 2 MDTs for this test"
25823
25824         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25825                 skip "Need server version at least 2.14.51"
25826
25827         local testdir
25828         local inherit
25829         local inherit_rr
25830
25831         testdir=$DIR/${tdir}-s1
25832         mkdir $testdir || error "mkdir $testdir failed"
25833         mkdir $testdir/rr || error "mkdir rr failed"
25834         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25835         # default max_inherit is -1, default max_inherit_rr is 0
25836         $LFS setdirstripe -D -c 1 $testdir/rr ||
25837                 error "setdirstripe rr failed"
25838         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25839                 error "setdirstripe qos failed"
25840         test_qos_mkdir "mkdir" 1
25841
25842         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25843         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25844         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25845         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25846         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25847
25848         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25849         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25850         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25851         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25852         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25853         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25854         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25855                 error "level2 shouldn't have default LMV" || true
25856 }
25857 run_test 413c "mkdir with default LMV max inherit rr"
25858
25859 test_413d() {
25860         (( MDSCOUNT >= 2 )) ||
25861                 skip "We need at least 2 MDTs for this test"
25862
25863         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25864                 skip "Need server version at least 2.14.51"
25865
25866         local lmv_qos_threshold_rr
25867
25868         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25869                 head -n1)
25870         stack_trap "$LCTL set_param \
25871                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25872
25873         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25874         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25875         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25876                 error "$tdir shouldn't have default LMV"
25877         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25878                 error "mkdir sub failed"
25879
25880         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25881
25882         (( count == 100 )) || error "$count subdirs on MDT0"
25883 }
25884 run_test 413d "inherit ROOT default LMV"
25885
25886 test_413e() {
25887         (( MDSCOUNT >= 2 )) ||
25888                 skip "We need at least 2 MDTs for this test"
25889         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25890                 skip "Need server version at least 2.14.55"
25891
25892         local testdir=$DIR/$tdir
25893         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25894         local max_inherit
25895         local sub_max_inherit
25896
25897         mkdir -p $testdir || error "failed to create $testdir"
25898
25899         # set default max-inherit to -1 if stripe count is 0 or 1
25900         $LFS setdirstripe -D -c 1 $testdir ||
25901                 error "failed to set default LMV"
25902         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25903         (( max_inherit == -1 )) ||
25904                 error "wrong max_inherit value $max_inherit"
25905
25906         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25907         $LFS setdirstripe -D -c -1 $testdir ||
25908                 error "failed to set default LMV"
25909         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25910         (( max_inherit > 0 )) ||
25911                 error "wrong max_inherit value $max_inherit"
25912
25913         # and the subdir will decrease the max_inherit by 1
25914         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25915         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25916         (( sub_max_inherit == max_inherit - 1)) ||
25917                 error "wrong max-inherit of subdir $sub_max_inherit"
25918
25919         # check specified --max-inherit and warning message
25920         stack_trap "rm -f $tmpfile"
25921         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25922                 error "failed to set default LMV"
25923         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25924         (( max_inherit == -1 )) ||
25925                 error "wrong max_inherit value $max_inherit"
25926
25927         # check the warning messages
25928         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25929                 error "failed to detect warning string"
25930         fi
25931 }
25932 run_test 413e "check default max-inherit value"
25933
25934 test_fs_dmv_inherit()
25935 {
25936         local testdir=$DIR/$tdir
25937
25938         local count
25939         local inherit
25940         local inherit_rr
25941
25942         for i in 1 2 3; do
25943                 mkdir $testdir || error "mkdir $testdir failed"
25944                 count=$($LFS getdirstripe -D -c $testdir)
25945                 (( count == 1 )) ||
25946                         error "$testdir default LMV count mismatch $count != 1"
25947                 inherit=$($LFS getdirstripe -D -X $testdir)
25948                 (( inherit == 3 - i )) ||
25949                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25950                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25951                 (( inherit_rr == 3 - i )) ||
25952                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25953                 testdir=$testdir/sub
25954         done
25955
25956         mkdir $testdir || error "mkdir $testdir failed"
25957         count=$($LFS getdirstripe -D -c $testdir)
25958         (( count == 0 )) ||
25959                 error "$testdir default LMV count not zero: $count"
25960 }
25961
25962 test_413f() {
25963         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25964
25965         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25966                 skip "Need server version at least 2.14.55"
25967
25968         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25969                 error "dump $DIR default LMV failed"
25970         stack_trap "setfattr --restore=$TMP/dmv.ea"
25971
25972         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25973                 error "set $DIR default LMV failed"
25974
25975         test_fs_dmv_inherit
25976 }
25977 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25978
25979 test_413g() {
25980         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25981
25982         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
25983         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25984                 error "dump $DIR default LMV failed"
25985         stack_trap "setfattr --restore=$TMP/dmv.ea"
25986
25987         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25988                 error "set $DIR default LMV failed"
25989
25990         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
25991                 error "mount $MOUNT2 failed"
25992         stack_trap "umount_client $MOUNT2"
25993
25994         local saved_DIR=$DIR
25995
25996         export DIR=$MOUNT2
25997
25998         stack_trap "export DIR=$saved_DIR"
25999
26000         # first check filesystem-wide default LMV inheritance
26001         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26002
26003         # then check subdirs are spread to all MDTs
26004         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26005
26006         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26007
26008         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26009 }
26010 run_test 413g "enforce ROOT default LMV on subdir mount"
26011
26012 test_413z() {
26013         local pids=""
26014         local subdir
26015         local pid
26016
26017         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26018                 unlinkmany $subdir/f. 1000 &
26019                 pids="$pids $!"
26020         done
26021
26022         for pid in $pids; do
26023                 wait $pid
26024         done
26025 }
26026 run_test 413z "413 test cleanup"
26027
26028 test_414() {
26029 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26030         $LCTL set_param fail_loc=0x80000521
26031         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26032         rm -f $DIR/$tfile
26033 }
26034 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26035
26036 test_415() {
26037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26038         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26039                 skip "Need server version at least 2.11.52"
26040
26041         # LU-11102
26042         local total
26043         local setattr_pid
26044         local start_time
26045         local end_time
26046         local duration
26047
26048         total=500
26049         # this test may be slow on ZFS
26050         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26051
26052         # though this test is designed for striped directory, let's test normal
26053         # directory too since lock is always saved as CoS lock.
26054         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26055         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26056
26057         (
26058                 while true; do
26059                         touch $DIR/$tdir
26060                 done
26061         ) &
26062         setattr_pid=$!
26063
26064         start_time=$(date +%s)
26065         for i in $(seq $total); do
26066                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26067                         > /dev/null
26068         done
26069         end_time=$(date +%s)
26070         duration=$((end_time - start_time))
26071
26072         kill -9 $setattr_pid
26073
26074         echo "rename $total files took $duration sec"
26075         [ $duration -lt 100 ] || error "rename took $duration sec"
26076 }
26077 run_test 415 "lock revoke is not missing"
26078
26079 test_416() {
26080         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26081                 skip "Need server version at least 2.11.55"
26082
26083         # define OBD_FAIL_OSD_TXN_START    0x19a
26084         do_facet mds1 lctl set_param fail_loc=0x19a
26085
26086         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26087
26088         true
26089 }
26090 run_test 416 "transaction start failure won't cause system hung"
26091
26092 cleanup_417() {
26093         trap 0
26094         do_nodes $(comma_list $(mdts_nodes)) \
26095                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26096         do_nodes $(comma_list $(mdts_nodes)) \
26097                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26098         do_nodes $(comma_list $(mdts_nodes)) \
26099                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26100 }
26101
26102 test_417() {
26103         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26104         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26105                 skip "Need MDS version at least 2.11.56"
26106
26107         trap cleanup_417 RETURN EXIT
26108
26109         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26110         do_nodes $(comma_list $(mdts_nodes)) \
26111                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26112         $LFS migrate -m 0 $DIR/$tdir.1 &&
26113                 error "migrate dir $tdir.1 should fail"
26114
26115         do_nodes $(comma_list $(mdts_nodes)) \
26116                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26117         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26118                 error "create remote dir $tdir.2 should fail"
26119
26120         do_nodes $(comma_list $(mdts_nodes)) \
26121                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26122         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26123                 error "create striped dir $tdir.3 should fail"
26124         true
26125 }
26126 run_test 417 "disable remote dir, striped dir and dir migration"
26127
26128 # Checks that the outputs of df [-i] and lfs df [-i] match
26129 #
26130 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26131 check_lfs_df() {
26132         local dir=$2
26133         local inodes
26134         local df_out
26135         local lfs_df_out
26136         local count
26137         local passed=false
26138
26139         # blocks or inodes
26140         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26141
26142         for count in {1..100}; do
26143                 do_nodes "$CLIENTS" \
26144                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26145                 sync; sleep 0.2
26146
26147                 # read the lines of interest
26148                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26149                         error "df $inodes $dir | tail -n +2 failed"
26150                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26151                         error "lfs df $inodes $dir | grep summary: failed"
26152
26153                 # skip first substrings of each output as they are different
26154                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26155                 # compare the two outputs
26156                 passed=true
26157                 #  skip "available" on MDT until LU-13997 is fixed.
26158                 #for i in {1..5}; do
26159                 for i in 1 2 4 5; do
26160                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26161                 done
26162                 $passed && break
26163         done
26164
26165         if ! $passed; then
26166                 df -P $inodes $dir
26167                 echo
26168                 lfs df $inodes $dir
26169                 error "df and lfs df $1 output mismatch: "      \
26170                       "df ${inodes}: ${df_out[*]}, "            \
26171                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26172         fi
26173 }
26174
26175 test_418() {
26176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26177
26178         local dir=$DIR/$tdir
26179         local numfiles=$((RANDOM % 4096 + 2))
26180         local numblocks=$((RANDOM % 256 + 1))
26181
26182         wait_delete_completed
26183         test_mkdir $dir
26184
26185         # check block output
26186         check_lfs_df blocks $dir
26187         # check inode output
26188         check_lfs_df inodes $dir
26189
26190         # create a single file and retest
26191         echo "Creating a single file and testing"
26192         createmany -o $dir/$tfile- 1 &>/dev/null ||
26193                 error "creating 1 file in $dir failed"
26194         check_lfs_df blocks $dir
26195         check_lfs_df inodes $dir
26196
26197         # create a random number of files
26198         echo "Creating $((numfiles - 1)) files and testing"
26199         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26200                 error "creating $((numfiles - 1)) files in $dir failed"
26201
26202         # write a random number of blocks to the first test file
26203         echo "Writing $numblocks 4K blocks and testing"
26204         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26205                 count=$numblocks &>/dev/null ||
26206                 error "dd to $dir/${tfile}-0 failed"
26207
26208         # retest
26209         check_lfs_df blocks $dir
26210         check_lfs_df inodes $dir
26211
26212         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26213                 error "unlinking $numfiles files in $dir failed"
26214 }
26215 run_test 418 "df and lfs df outputs match"
26216
26217 test_419()
26218 {
26219         local dir=$DIR/$tdir
26220
26221         mkdir -p $dir
26222         touch $dir/file
26223
26224         cancel_lru_locks mdc
26225
26226         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26227         $LCTL set_param fail_loc=0x1410
26228         cat $dir/file
26229         $LCTL set_param fail_loc=0
26230         rm -rf $dir
26231 }
26232 run_test 419 "Verify open file by name doesn't crash kernel"
26233
26234 test_420()
26235 {
26236         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26237                 skip "Need MDS version at least 2.12.53"
26238
26239         local SAVE_UMASK=$(umask)
26240         local dir=$DIR/$tdir
26241         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26242
26243         mkdir -p $dir
26244         umask 0000
26245         mkdir -m03777 $dir/testdir
26246         ls -dn $dir/testdir
26247         # Need to remove trailing '.' when SELinux is enabled
26248         local dirperms=$(ls -dn $dir/testdir |
26249                          awk '{ sub(/\.$/, "", $1); print $1}')
26250         [ $dirperms == "drwxrwsrwt" ] ||
26251                 error "incorrect perms on $dir/testdir"
26252
26253         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26254                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26255         ls -n $dir/testdir/testfile
26256         local fileperms=$(ls -n $dir/testdir/testfile |
26257                           awk '{ sub(/\.$/, "", $1); print $1}')
26258         [ $fileperms == "-rwxr-xr-x" ] ||
26259                 error "incorrect perms on $dir/testdir/testfile"
26260
26261         umask $SAVE_UMASK
26262 }
26263 run_test 420 "clear SGID bit on non-directories for non-members"
26264
26265 test_421a() {
26266         local cnt
26267         local fid1
26268         local fid2
26269
26270         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26271                 skip "Need MDS version at least 2.12.54"
26272
26273         test_mkdir $DIR/$tdir
26274         createmany -o $DIR/$tdir/f 3
26275         cnt=$(ls -1 $DIR/$tdir | wc -l)
26276         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26277
26278         fid1=$(lfs path2fid $DIR/$tdir/f1)
26279         fid2=$(lfs path2fid $DIR/$tdir/f2)
26280         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26281
26282         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26283         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26284
26285         cnt=$(ls -1 $DIR/$tdir | wc -l)
26286         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26287
26288         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26289         createmany -o $DIR/$tdir/f 3
26290         cnt=$(ls -1 $DIR/$tdir | wc -l)
26291         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26292
26293         fid1=$(lfs path2fid $DIR/$tdir/f1)
26294         fid2=$(lfs path2fid $DIR/$tdir/f2)
26295         echo "remove using fsname $FSNAME"
26296         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26297
26298         cnt=$(ls -1 $DIR/$tdir | wc -l)
26299         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26300 }
26301 run_test 421a "simple rm by fid"
26302
26303 test_421b() {
26304         local cnt
26305         local FID1
26306         local FID2
26307
26308         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26309                 skip "Need MDS version at least 2.12.54"
26310
26311         test_mkdir $DIR/$tdir
26312         createmany -o $DIR/$tdir/f 3
26313         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26314         MULTIPID=$!
26315
26316         FID1=$(lfs path2fid $DIR/$tdir/f1)
26317         FID2=$(lfs path2fid $DIR/$tdir/f2)
26318         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26319
26320         kill -USR1 $MULTIPID
26321         wait
26322
26323         cnt=$(ls $DIR/$tdir | wc -l)
26324         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26325 }
26326 run_test 421b "rm by fid on open file"
26327
26328 test_421c() {
26329         local cnt
26330         local FIDS
26331
26332         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26333                 skip "Need MDS version at least 2.12.54"
26334
26335         test_mkdir $DIR/$tdir
26336         createmany -o $DIR/$tdir/f 3
26337         touch $DIR/$tdir/$tfile
26338         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26339         cnt=$(ls -1 $DIR/$tdir | wc -l)
26340         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26341
26342         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26343         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26344
26345         cnt=$(ls $DIR/$tdir | wc -l)
26346         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26347 }
26348 run_test 421c "rm by fid against hardlinked files"
26349
26350 test_421d() {
26351         local cnt
26352         local FIDS
26353
26354         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26355                 skip "Need MDS version at least 2.12.54"
26356
26357         test_mkdir $DIR/$tdir
26358         createmany -o $DIR/$tdir/f 4097
26359         cnt=$(ls -1 $DIR/$tdir | wc -l)
26360         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26361
26362         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26363         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26364
26365         cnt=$(ls $DIR/$tdir | wc -l)
26366         rm -rf $DIR/$tdir
26367         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26368 }
26369 run_test 421d "rmfid en masse"
26370
26371 test_421e() {
26372         local cnt
26373         local FID
26374
26375         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26376         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26377                 skip "Need MDS version at least 2.12.54"
26378
26379         mkdir -p $DIR/$tdir
26380         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26381         createmany -o $DIR/$tdir/striped_dir/f 512
26382         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26383         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26384
26385         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26386                 sed "s/[/][^:]*://g")
26387         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26388
26389         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26390         rm -rf $DIR/$tdir
26391         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26392 }
26393 run_test 421e "rmfid in DNE"
26394
26395 test_421f() {
26396         local cnt
26397         local FID
26398
26399         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26400                 skip "Need MDS version at least 2.12.54"
26401
26402         test_mkdir $DIR/$tdir
26403         touch $DIR/$tdir/f
26404         cnt=$(ls -1 $DIR/$tdir | wc -l)
26405         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26406
26407         FID=$(lfs path2fid $DIR/$tdir/f)
26408         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26409         # rmfid should fail
26410         cnt=$(ls -1 $DIR/$tdir | wc -l)
26411         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26412
26413         chmod a+rw $DIR/$tdir
26414         ls -la $DIR/$tdir
26415         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26416         # rmfid should fail
26417         cnt=$(ls -1 $DIR/$tdir | wc -l)
26418         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26419
26420         rm -f $DIR/$tdir/f
26421         $RUNAS touch $DIR/$tdir/f
26422         FID=$(lfs path2fid $DIR/$tdir/f)
26423         echo "rmfid as root"
26424         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26425         cnt=$(ls -1 $DIR/$tdir | wc -l)
26426         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26427
26428         rm -f $DIR/$tdir/f
26429         $RUNAS touch $DIR/$tdir/f
26430         cnt=$(ls -1 $DIR/$tdir | wc -l)
26431         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26432         FID=$(lfs path2fid $DIR/$tdir/f)
26433         # rmfid w/o user_fid2path mount option should fail
26434         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26435         cnt=$(ls -1 $DIR/$tdir | wc -l)
26436         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26437
26438         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26439         stack_trap "rmdir $tmpdir"
26440         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26441                 error "failed to mount client'"
26442         stack_trap "umount_client $tmpdir"
26443
26444         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26445         # rmfid should succeed
26446         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26447         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26448
26449         # rmfid shouldn't allow to remove files due to dir's permission
26450         chmod a+rwx $tmpdir/$tdir
26451         touch $tmpdir/$tdir/f
26452         ls -la $tmpdir/$tdir
26453         FID=$(lfs path2fid $tmpdir/$tdir/f)
26454         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26455         return 0
26456 }
26457 run_test 421f "rmfid checks permissions"
26458
26459 test_421g() {
26460         local cnt
26461         local FIDS
26462
26463         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26464         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26465                 skip "Need MDS version at least 2.12.54"
26466
26467         mkdir -p $DIR/$tdir
26468         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26469         createmany -o $DIR/$tdir/striped_dir/f 512
26470         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26471         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26472
26473         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26474                 sed "s/[/][^:]*://g")
26475
26476         rm -f $DIR/$tdir/striped_dir/f1*
26477         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26478         removed=$((512 - cnt))
26479
26480         # few files have been just removed, so we expect
26481         # rmfid to fail on their fids
26482         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26483         [ $removed != $errors ] && error "$errors != $removed"
26484
26485         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26486         rm -rf $DIR/$tdir
26487         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26488 }
26489 run_test 421g "rmfid to return errors properly"
26490
26491 test_422() {
26492         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26493         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26494         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26495         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26496         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26497
26498         local amc=$(at_max_get client)
26499         local amo=$(at_max_get mds1)
26500         local timeout=`lctl get_param -n timeout`
26501
26502         at_max_set 0 client
26503         at_max_set 0 mds1
26504
26505 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26506         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26507                         fail_val=$(((2*timeout + 10)*1000))
26508         touch $DIR/$tdir/d3/file &
26509         sleep 2
26510 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26511         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26512                         fail_val=$((2*timeout + 5))
26513         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26514         local pid=$!
26515         sleep 1
26516         kill -9 $pid
26517         sleep $((2 * timeout))
26518         echo kill $pid
26519         kill -9 $pid
26520         lctl mark touch
26521         touch $DIR/$tdir/d2/file3
26522         touch $DIR/$tdir/d2/file4
26523         touch $DIR/$tdir/d2/file5
26524
26525         wait
26526         at_max_set $amc client
26527         at_max_set $amo mds1
26528
26529         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26530         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26531                 error "Watchdog is always throttled"
26532 }
26533 run_test 422 "kill a process with RPC in progress"
26534
26535 stat_test() {
26536     df -h $MOUNT &
26537     df -h $MOUNT &
26538     df -h $MOUNT &
26539     df -h $MOUNT &
26540     df -h $MOUNT &
26541     df -h $MOUNT &
26542 }
26543
26544 test_423() {
26545     local _stats
26546     # ensure statfs cache is expired
26547     sleep 2;
26548
26549     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26550     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26551
26552     return 0
26553 }
26554 run_test 423 "statfs should return a right data"
26555
26556 test_424() {
26557 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26558         $LCTL set_param fail_loc=0x80000522
26559         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26560         rm -f $DIR/$tfile
26561 }
26562 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26563
26564 test_425() {
26565         test_mkdir -c -1 $DIR/$tdir
26566         $LFS setstripe -c -1 $DIR/$tdir
26567
26568         lru_resize_disable "" 100
26569         stack_trap "lru_resize_enable" EXIT
26570
26571         sleep 5
26572
26573         for i in $(seq $((MDSCOUNT * 125))); do
26574                 local t=$DIR/$tdir/$tfile_$i
26575
26576                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26577                         error_noexit "Create file $t"
26578         done
26579         stack_trap "rm -rf $DIR/$tdir" EXIT
26580
26581         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26582                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26583                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26584
26585                 [ $lock_count -le $lru_size ] ||
26586                         error "osc lock count $lock_count > lru size $lru_size"
26587         done
26588
26589         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26590                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26591                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26592
26593                 [ $lock_count -le $lru_size ] ||
26594                         error "mdc lock count $lock_count > lru size $lru_size"
26595         done
26596 }
26597 run_test 425 "lock count should not exceed lru size"
26598
26599 test_426() {
26600         splice-test -r $DIR/$tfile
26601         splice-test -rd $DIR/$tfile
26602         splice-test $DIR/$tfile
26603         splice-test -d $DIR/$tfile
26604 }
26605 run_test 426 "splice test on Lustre"
26606
26607 test_427() {
26608         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26609         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26610                 skip "Need MDS version at least 2.12.4"
26611         local log
26612
26613         mkdir $DIR/$tdir
26614         mkdir $DIR/$tdir/1
26615         mkdir $DIR/$tdir/2
26616         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26617         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26618
26619         $LFS getdirstripe $DIR/$tdir/1/dir
26620
26621         #first setfattr for creating updatelog
26622         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26623
26624 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26625         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26626         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26627         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26628
26629         sleep 2
26630         fail mds2
26631         wait_recovery_complete mds2 $((2*TIMEOUT))
26632
26633         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26634         echo $log | grep "get update log failed" &&
26635                 error "update log corruption is detected" || true
26636 }
26637 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26638
26639 test_428() {
26640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26641         local cache_limit=$CACHE_MAX
26642
26643         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26644         $LCTL set_param -n llite.*.max_cached_mb=64
26645
26646         mkdir $DIR/$tdir
26647         $LFS setstripe -c 1 $DIR/$tdir
26648         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26649         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26650         #test write
26651         for f in $(seq 4); do
26652                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26653         done
26654         wait
26655
26656         cancel_lru_locks osc
26657         # Test read
26658         for f in $(seq 4); do
26659                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26660         done
26661         wait
26662 }
26663 run_test 428 "large block size IO should not hang"
26664
26665 test_429() { # LU-7915 / LU-10948
26666         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26667         local testfile=$DIR/$tfile
26668         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26669         local new_flag=1
26670         local first_rpc
26671         local second_rpc
26672         local third_rpc
26673
26674         $LCTL get_param $ll_opencache_threshold_count ||
26675                 skip "client does not have opencache parameter"
26676
26677         set_opencache $new_flag
26678         stack_trap "restore_opencache"
26679         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26680                 error "enable opencache failed"
26681         touch $testfile
26682         # drop MDC DLM locks
26683         cancel_lru_locks mdc
26684         # clear MDC RPC stats counters
26685         $LCTL set_param $mdc_rpcstats=clear
26686
26687         # According to the current implementation, we need to run 3 times
26688         # open & close file to verify if opencache is enabled correctly.
26689         # 1st, RPCs are sent for lookup/open and open handle is released on
26690         #      close finally.
26691         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26692         #      so open handle won't be released thereafter.
26693         # 3rd, No RPC is sent out.
26694         $MULTIOP $testfile oc || error "multiop failed"
26695         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26696         echo "1st: $first_rpc RPCs in flight"
26697
26698         $MULTIOP $testfile oc || error "multiop failed"
26699         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26700         echo "2nd: $second_rpc RPCs in flight"
26701
26702         $MULTIOP $testfile oc || error "multiop failed"
26703         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26704         echo "3rd: $third_rpc RPCs in flight"
26705
26706         #verify no MDC RPC is sent
26707         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26708 }
26709 run_test 429 "verify if opencache flag on client side does work"
26710
26711 lseek_test_430() {
26712         local offset
26713         local file=$1
26714
26715         # data at [200K, 400K)
26716         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26717                 error "256K->512K dd fails"
26718         # data at [2M, 3M)
26719         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26720                 error "2M->3M dd fails"
26721         # data at [4M, 5M)
26722         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26723                 error "4M->5M dd fails"
26724         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26725         # start at first component hole #1
26726         printf "Seeking hole from 1000 ... "
26727         offset=$(lseek_test -l 1000 $file)
26728         echo $offset
26729         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26730         printf "Seeking data from 1000 ... "
26731         offset=$(lseek_test -d 1000 $file)
26732         echo $offset
26733         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26734
26735         # start at first component data block
26736         printf "Seeking hole from 300000 ... "
26737         offset=$(lseek_test -l 300000 $file)
26738         echo $offset
26739         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26740         printf "Seeking data from 300000 ... "
26741         offset=$(lseek_test -d 300000 $file)
26742         echo $offset
26743         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26744
26745         # start at the first component but beyond end of object size
26746         printf "Seeking hole from 1000000 ... "
26747         offset=$(lseek_test -l 1000000 $file)
26748         echo $offset
26749         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26750         printf "Seeking data from 1000000 ... "
26751         offset=$(lseek_test -d 1000000 $file)
26752         echo $offset
26753         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26754
26755         # start at second component stripe 2 (empty file)
26756         printf "Seeking hole from 1500000 ... "
26757         offset=$(lseek_test -l 1500000 $file)
26758         echo $offset
26759         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26760         printf "Seeking data from 1500000 ... "
26761         offset=$(lseek_test -d 1500000 $file)
26762         echo $offset
26763         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26764
26765         # start at second component stripe 1 (all data)
26766         printf "Seeking hole from 3000000 ... "
26767         offset=$(lseek_test -l 3000000 $file)
26768         echo $offset
26769         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26770         printf "Seeking data from 3000000 ... "
26771         offset=$(lseek_test -d 3000000 $file)
26772         echo $offset
26773         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26774
26775         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26776                 error "2nd dd fails"
26777         echo "Add data block at 640K...1280K"
26778
26779         # start at before new data block, in hole
26780         printf "Seeking hole from 600000 ... "
26781         offset=$(lseek_test -l 600000 $file)
26782         echo $offset
26783         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26784         printf "Seeking data from 600000 ... "
26785         offset=$(lseek_test -d 600000 $file)
26786         echo $offset
26787         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26788
26789         # start at the first component new data block
26790         printf "Seeking hole from 1000000 ... "
26791         offset=$(lseek_test -l 1000000 $file)
26792         echo $offset
26793         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26794         printf "Seeking data from 1000000 ... "
26795         offset=$(lseek_test -d 1000000 $file)
26796         echo $offset
26797         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26798
26799         # start at second component stripe 2, new data
26800         printf "Seeking hole from 1200000 ... "
26801         offset=$(lseek_test -l 1200000 $file)
26802         echo $offset
26803         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26804         printf "Seeking data from 1200000 ... "
26805         offset=$(lseek_test -d 1200000 $file)
26806         echo $offset
26807         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26808
26809         # start beyond file end
26810         printf "Using offset > filesize ... "
26811         lseek_test -l 4000000 $file && error "lseek should fail"
26812         printf "Using offset > filesize ... "
26813         lseek_test -d 4000000 $file && error "lseek should fail"
26814
26815         printf "Done\n\n"
26816 }
26817
26818 test_430a() {
26819         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26820                 skip "MDT does not support SEEK_HOLE"
26821
26822         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26823                 skip "OST does not support SEEK_HOLE"
26824
26825         local file=$DIR/$tdir/$tfile
26826
26827         mkdir -p $DIR/$tdir
26828
26829         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26830         # OST stripe #1 will have continuous data at [1M, 3M)
26831         # OST stripe #2 is empty
26832         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26833         lseek_test_430 $file
26834         rm $file
26835         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26836         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26837         lseek_test_430 $file
26838         rm $file
26839         $LFS setstripe -c2 -S 512K $file
26840         echo "Two stripes, stripe size 512K"
26841         lseek_test_430 $file
26842         rm $file
26843         # FLR with stale mirror
26844         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26845                        -N -c2 -S 1M $file
26846         echo "Mirrored file:"
26847         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26848         echo "Plain 2 stripes 1M"
26849         lseek_test_430 $file
26850         rm $file
26851 }
26852 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26853
26854 test_430b() {
26855         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26856                 skip "OST does not support SEEK_HOLE"
26857
26858         local offset
26859         local file=$DIR/$tdir/$tfile
26860
26861         mkdir -p $DIR/$tdir
26862         # Empty layout lseek should fail
26863         $MCREATE $file
26864         # seek from 0
26865         printf "Seeking hole from 0 ... "
26866         lseek_test -l 0 $file && error "lseek should fail"
26867         printf "Seeking data from 0 ... "
26868         lseek_test -d 0 $file && error "lseek should fail"
26869         rm $file
26870
26871         # 1M-hole file
26872         $LFS setstripe -E 1M -c2 -E eof $file
26873         $TRUNCATE $file 1048576
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         lseek_test -d 1000000 $file && error "lseek should fail"
26880         rm $file
26881
26882         # full component followed by non-inited one
26883         $LFS setstripe -E 1M -c2 -E eof $file
26884         dd if=/dev/urandom of=$file bs=1M count=1
26885         printf "Seeking hole from 1000000 ... "
26886         offset=$(lseek_test -l 1000000 $file)
26887         echo $offset
26888         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26889         printf "Seeking hole from 1048576 ... "
26890         lseek_test -l 1048576 $file && error "lseek should fail"
26891         # init second component and truncate back
26892         echo "123" >> $file
26893         $TRUNCATE $file 1048576
26894         printf "Seeking hole from 1000000 ... "
26895         offset=$(lseek_test -l 1000000 $file)
26896         echo $offset
26897         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26898         printf "Seeking hole from 1048576 ... "
26899         lseek_test -l 1048576 $file && error "lseek should fail"
26900         # boundary checks for big values
26901         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26902         offset=$(lseek_test -d 0 $file.10g)
26903         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26904         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26905         offset=$(lseek_test -d 0 $file.100g)
26906         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26907         return 0
26908 }
26909 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26910
26911 test_430c() {
26912         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26913                 skip "OST does not support SEEK_HOLE"
26914
26915         local file=$DIR/$tdir/$tfile
26916         local start
26917
26918         mkdir -p $DIR/$tdir
26919         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26920
26921         # cp version 8.33+ prefers lseek over fiemap
26922         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26923                 start=$SECONDS
26924                 time cp $file /dev/null
26925                 (( SECONDS - start < 5 )) ||
26926                         error "cp: too long runtime $((SECONDS - start))"
26927
26928         fi
26929         # tar version 1.29+ supports SEEK_HOLE/DATA
26930         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26931                 start=$SECONDS
26932                 time tar cS $file - | cat > /dev/null
26933                 (( SECONDS - start < 5 )) ||
26934                         error "tar: too long runtime $((SECONDS - start))"
26935         fi
26936 }
26937 run_test 430c "lseek: external tools check"
26938
26939 test_431() { # LU-14187
26940         local file=$DIR/$tdir/$tfile
26941
26942         mkdir -p $DIR/$tdir
26943         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26944         dd if=/dev/urandom of=$file bs=4k count=1
26945         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26946         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26947         #define OBD_FAIL_OST_RESTART_IO 0x251
26948         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26949         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26950         cp $file $file.0
26951         cancel_lru_locks
26952         sync_all_data
26953         echo 3 > /proc/sys/vm/drop_caches
26954         diff  $file $file.0 || error "data diff"
26955 }
26956 run_test 431 "Restart transaction for IO"
26957
26958 cleanup_test_432() {
26959         do_facet mgs $LCTL nodemap_activate 0
26960         wait_nm_sync active
26961 }
26962
26963 test_432() {
26964         local tmpdir=$TMP/dir432
26965
26966         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26967                 skip "Need MDS version at least 2.14.52"
26968
26969         stack_trap cleanup_test_432 EXIT
26970         mkdir $DIR/$tdir
26971         mkdir $tmpdir
26972
26973         do_facet mgs $LCTL nodemap_activate 1
26974         wait_nm_sync active
26975         do_facet mgs $LCTL nodemap_modify --name default \
26976                 --property admin --value 1
26977         do_facet mgs $LCTL nodemap_modify --name default \
26978                 --property trusted --value 1
26979         cancel_lru_locks mdc
26980         wait_nm_sync default admin_nodemap
26981         wait_nm_sync default trusted_nodemap
26982
26983         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26984                grep -ci "Operation not permitted") -ne 0 ]; then
26985                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26986         fi
26987 }
26988 run_test 432 "mv dir from outside Lustre"
26989
26990 test_433() {
26991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26992
26993         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
26994                 skip "inode cache not supported"
26995
26996         $LCTL set_param llite.*.inode_cache=0
26997         stack_trap "$LCTL set_param llite.*.inode_cache=1"
26998
26999         local count=256
27000         local before
27001         local after
27002
27003         cancel_lru_locks mdc
27004         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27005         createmany -m $DIR/$tdir/f $count
27006         createmany -d $DIR/$tdir/d $count
27007         ls -l $DIR/$tdir > /dev/null
27008         stack_trap "rm -rf $DIR/$tdir"
27009
27010         before=$(num_objects)
27011         cancel_lru_locks mdc
27012         after=$(num_objects)
27013
27014         # sometimes even @before is less than 2 * count
27015         while (( before - after < count )); do
27016                 sleep 1
27017                 after=$(num_objects)
27018                 wait=$((wait + 1))
27019                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27020                 if (( wait > 60 )); then
27021                         error "inode slab grew from $before to $after"
27022                 fi
27023         done
27024
27025         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27026 }
27027 run_test 433 "ldlm lock cancel releases dentries and inodes"
27028
27029 prep_801() {
27030         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27031         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27032                 skip "Need server version at least 2.9.55"
27033
27034         start_full_debug_logging
27035 }
27036
27037 post_801() {
27038         stop_full_debug_logging
27039 }
27040
27041 barrier_stat() {
27042         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27043                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27044                            awk '/The barrier for/ { print $7 }')
27045                 echo $st
27046         else
27047                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27048                 echo \'$st\'
27049         fi
27050 }
27051
27052 barrier_expired() {
27053         local expired
27054
27055         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27056                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27057                           awk '/will be expired/ { print $7 }')
27058         else
27059                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27060         fi
27061
27062         echo $expired
27063 }
27064
27065 test_801a() {
27066         prep_801
27067
27068         echo "Start barrier_freeze at: $(date)"
27069         #define OBD_FAIL_BARRIER_DELAY          0x2202
27070         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27071         # Do not reduce barrier time - See LU-11873
27072         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27073
27074         sleep 2
27075         local b_status=$(barrier_stat)
27076         echo "Got barrier status at: $(date)"
27077         [ "$b_status" = "'freezing_p1'" ] ||
27078                 error "(1) unexpected barrier status $b_status"
27079
27080         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27081         wait
27082         b_status=$(barrier_stat)
27083         [ "$b_status" = "'frozen'" ] ||
27084                 error "(2) unexpected barrier status $b_status"
27085
27086         local expired=$(barrier_expired)
27087         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27088         sleep $((expired + 3))
27089
27090         b_status=$(barrier_stat)
27091         [ "$b_status" = "'expired'" ] ||
27092                 error "(3) unexpected barrier status $b_status"
27093
27094         # Do not reduce barrier time - See LU-11873
27095         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27096                 error "(4) fail to freeze barrier"
27097
27098         b_status=$(barrier_stat)
27099         [ "$b_status" = "'frozen'" ] ||
27100                 error "(5) unexpected barrier status $b_status"
27101
27102         echo "Start barrier_thaw at: $(date)"
27103         #define OBD_FAIL_BARRIER_DELAY          0x2202
27104         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27105         do_facet mgs $LCTL barrier_thaw $FSNAME &
27106
27107         sleep 2
27108         b_status=$(barrier_stat)
27109         echo "Got barrier status at: $(date)"
27110         [ "$b_status" = "'thawing'" ] ||
27111                 error "(6) unexpected barrier status $b_status"
27112
27113         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27114         wait
27115         b_status=$(barrier_stat)
27116         [ "$b_status" = "'thawed'" ] ||
27117                 error "(7) unexpected barrier status $b_status"
27118
27119         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27120         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27121         do_facet mgs $LCTL barrier_freeze $FSNAME
27122
27123         b_status=$(barrier_stat)
27124         [ "$b_status" = "'failed'" ] ||
27125                 error "(8) unexpected barrier status $b_status"
27126
27127         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27128         do_facet mgs $LCTL barrier_thaw $FSNAME
27129
27130         post_801
27131 }
27132 run_test 801a "write barrier user interfaces and stat machine"
27133
27134 test_801b() {
27135         prep_801
27136
27137         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27138         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27139         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27140         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27141         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27142
27143         cancel_lru_locks mdc
27144
27145         # 180 seconds should be long enough
27146         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27147
27148         local b_status=$(barrier_stat)
27149         [ "$b_status" = "'frozen'" ] ||
27150                 error "(6) unexpected barrier status $b_status"
27151
27152         mkdir $DIR/$tdir/d0/d10 &
27153         mkdir_pid=$!
27154
27155         touch $DIR/$tdir/d1/f13 &
27156         touch_pid=$!
27157
27158         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27159         ln_pid=$!
27160
27161         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27162         mv_pid=$!
27163
27164         rm -f $DIR/$tdir/d4/f12 &
27165         rm_pid=$!
27166
27167         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27168
27169         # To guarantee taht the 'stat' is not blocked
27170         b_status=$(barrier_stat)
27171         [ "$b_status" = "'frozen'" ] ||
27172                 error "(8) unexpected barrier status $b_status"
27173
27174         # let above commands to run at background
27175         sleep 5
27176
27177         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27178         ps -p $touch_pid || error "(10) touch should be blocked"
27179         ps -p $ln_pid || error "(11) link should be blocked"
27180         ps -p $mv_pid || error "(12) rename should be blocked"
27181         ps -p $rm_pid || error "(13) unlink should be blocked"
27182
27183         b_status=$(barrier_stat)
27184         [ "$b_status" = "'frozen'" ] ||
27185                 error "(14) unexpected barrier status $b_status"
27186
27187         do_facet mgs $LCTL barrier_thaw $FSNAME
27188         b_status=$(barrier_stat)
27189         [ "$b_status" = "'thawed'" ] ||
27190                 error "(15) unexpected barrier status $b_status"
27191
27192         wait $mkdir_pid || error "(16) mkdir should succeed"
27193         wait $touch_pid || error "(17) touch should succeed"
27194         wait $ln_pid || error "(18) link should succeed"
27195         wait $mv_pid || error "(19) rename should succeed"
27196         wait $rm_pid || error "(20) unlink should succeed"
27197
27198         post_801
27199 }
27200 run_test 801b "modification will be blocked by write barrier"
27201
27202 test_801c() {
27203         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27204
27205         prep_801
27206
27207         stop mds2 || error "(1) Fail to stop mds2"
27208
27209         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27210
27211         local b_status=$(barrier_stat)
27212         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27213                 do_facet mgs $LCTL barrier_thaw $FSNAME
27214                 error "(2) unexpected barrier status $b_status"
27215         }
27216
27217         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27218                 error "(3) Fail to rescan barrier bitmap"
27219
27220         # Do not reduce barrier time - See LU-11873
27221         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27222
27223         b_status=$(barrier_stat)
27224         [ "$b_status" = "'frozen'" ] ||
27225                 error "(4) unexpected barrier status $b_status"
27226
27227         do_facet mgs $LCTL barrier_thaw $FSNAME
27228         b_status=$(barrier_stat)
27229         [ "$b_status" = "'thawed'" ] ||
27230                 error "(5) unexpected barrier status $b_status"
27231
27232         local devname=$(mdsdevname 2)
27233
27234         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27235
27236         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27237                 error "(7) Fail to rescan barrier bitmap"
27238
27239         post_801
27240 }
27241 run_test 801c "rescan barrier bitmap"
27242
27243 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27244 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27245 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27246 saved_MOUNT_OPTS=$MOUNT_OPTS
27247
27248 cleanup_802a() {
27249         trap 0
27250
27251         stopall
27252         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27253         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27254         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27255         MOUNT_OPTS=$saved_MOUNT_OPTS
27256         setupall
27257 }
27258
27259 test_802a() {
27260         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27261         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27262         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27263                 skip "Need server version at least 2.9.55"
27264
27265         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27266
27267         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27268
27269         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27270                 error "(2) Fail to copy"
27271
27272         trap cleanup_802a EXIT
27273
27274         # sync by force before remount as readonly
27275         sync; sync_all_data; sleep 3; sync_all_data
27276
27277         stopall
27278
27279         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27280         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27281         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27282
27283         echo "Mount the server as read only"
27284         setupall server_only || error "(3) Fail to start servers"
27285
27286         echo "Mount client without ro should fail"
27287         mount_client $MOUNT &&
27288                 error "(4) Mount client without 'ro' should fail"
27289
27290         echo "Mount client with ro should succeed"
27291         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27292         mount_client $MOUNT ||
27293                 error "(5) Mount client with 'ro' should succeed"
27294
27295         echo "Modify should be refused"
27296         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27297
27298         echo "Read should be allowed"
27299         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27300                 error "(7) Read should succeed under ro mode"
27301
27302         cleanup_802a
27303 }
27304 run_test 802a "simulate readonly device"
27305
27306 test_802b() {
27307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27308         remote_mds_nodsh && skip "remote MDS with nodsh"
27309
27310         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27311                 skip "readonly option not available"
27312
27313         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27314
27315         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27316                 error "(2) Fail to copy"
27317
27318         # write back all cached data before setting MDT to readonly
27319         cancel_lru_locks
27320         sync_all_data
27321
27322         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27323         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27324
27325         echo "Modify should be refused"
27326         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27327
27328         echo "Read should be allowed"
27329         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27330                 error "(7) Read should succeed under ro mode"
27331
27332         # disable readonly
27333         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27334 }
27335 run_test 802b "be able to set MDTs to readonly"
27336
27337 test_803a() {
27338         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27339         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27340                 skip "MDS needs to be newer than 2.10.54"
27341
27342         mkdir_on_mdt0 $DIR/$tdir
27343         # Create some objects on all MDTs to trigger related logs objects
27344         for idx in $(seq $MDSCOUNT); do
27345                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27346                         $DIR/$tdir/dir${idx} ||
27347                         error "Fail to create $DIR/$tdir/dir${idx}"
27348         done
27349
27350         sync; sleep 3
27351         wait_delete_completed # ensure old test cleanups are finished
27352         echo "before create:"
27353         $LFS df -i $MOUNT
27354         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27355
27356         for i in {1..10}; do
27357                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27358                         error "Fail to create $DIR/$tdir/foo$i"
27359         done
27360
27361         sync; sleep 3
27362         echo "after create:"
27363         $LFS df -i $MOUNT
27364         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27365
27366         # allow for an llog to be cleaned up during the test
27367         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27368                 error "before ($before_used) + 10 > after ($after_used)"
27369
27370         for i in {1..10}; do
27371                 rm -rf $DIR/$tdir/foo$i ||
27372                         error "Fail to remove $DIR/$tdir/foo$i"
27373         done
27374
27375         sleep 3 # avoid MDT return cached statfs
27376         wait_delete_completed
27377         echo "after unlink:"
27378         $LFS df -i $MOUNT
27379         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27380
27381         # allow for an llog to be created during the test
27382         [ $after_used -le $((before_used + 1)) ] ||
27383                 error "after ($after_used) > before ($before_used) + 1"
27384 }
27385 run_test 803a "verify agent object for remote object"
27386
27387 test_803b() {
27388         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27389         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27390                 skip "MDS needs to be newer than 2.13.56"
27391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27392
27393         for i in $(seq 0 $((MDSCOUNT - 1))); do
27394                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27395         done
27396
27397         local before=0
27398         local after=0
27399
27400         local tmp
27401
27402         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27403         for i in $(seq 0 $((MDSCOUNT - 1))); do
27404                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27405                         awk '/getattr/ { print $2 }')
27406                 before=$((before + tmp))
27407         done
27408         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27409         for i in $(seq 0 $((MDSCOUNT - 1))); do
27410                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27411                         awk '/getattr/ { print $2 }')
27412                 after=$((after + tmp))
27413         done
27414
27415         [ $before -eq $after ] || error "getattr count $before != $after"
27416 }
27417 run_test 803b "remote object can getattr from cache"
27418
27419 test_804() {
27420         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27421         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27422                 skip "MDS needs to be newer than 2.10.54"
27423         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27424
27425         mkdir -p $DIR/$tdir
27426         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27427                 error "Fail to create $DIR/$tdir/dir0"
27428
27429         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27430         local dev=$(mdsdevname 2)
27431
27432         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27433                 grep ${fid} || error "NOT found agent entry for dir0"
27434
27435         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27436                 error "Fail to create $DIR/$tdir/dir1"
27437
27438         touch $DIR/$tdir/dir1/foo0 ||
27439                 error "Fail to create $DIR/$tdir/dir1/foo0"
27440         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27441         local rc=0
27442
27443         for idx in $(seq $MDSCOUNT); do
27444                 dev=$(mdsdevname $idx)
27445                 do_facet mds${idx} \
27446                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27447                         grep ${fid} && rc=$idx
27448         done
27449
27450         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27451                 error "Fail to rename foo0 to foo1"
27452         if [ $rc -eq 0 ]; then
27453                 for idx in $(seq $MDSCOUNT); do
27454                         dev=$(mdsdevname $idx)
27455                         do_facet mds${idx} \
27456                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27457                         grep ${fid} && rc=$idx
27458                 done
27459         fi
27460
27461         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27462                 error "Fail to rename foo1 to foo2"
27463         if [ $rc -eq 0 ]; then
27464                 for idx in $(seq $MDSCOUNT); do
27465                         dev=$(mdsdevname $idx)
27466                         do_facet mds${idx} \
27467                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27468                         grep ${fid} && rc=$idx
27469                 done
27470         fi
27471
27472         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27473
27474         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27475                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27476         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27477                 error "Fail to rename foo2 to foo0"
27478         unlink $DIR/$tdir/dir1/foo0 ||
27479                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27480         rm -rf $DIR/$tdir/dir0 ||
27481                 error "Fail to rm $DIR/$tdir/dir0"
27482
27483         for idx in $(seq $MDSCOUNT); do
27484                 rc=0
27485
27486                 stop mds${idx}
27487                 dev=$(mdsdevname $idx)
27488                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27489                         rc=$?
27490                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27491                         error "mount mds$idx failed"
27492                 df $MOUNT > /dev/null 2>&1
27493
27494                 # e2fsck should not return error
27495                 [ $rc -eq 0 ] ||
27496                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27497         done
27498 }
27499 run_test 804 "verify agent entry for remote entry"
27500
27501 cleanup_805() {
27502         do_facet $SINGLEMDS zfs set quota=$old $fsset
27503         unlinkmany $DIR/$tdir/f- 1000000
27504         trap 0
27505 }
27506
27507 test_805() {
27508         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27509         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27510         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27511                 skip "netfree not implemented before 0.7"
27512         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27513                 skip "Need MDS version at least 2.10.57"
27514
27515         local fsset
27516         local freekb
27517         local usedkb
27518         local old
27519         local quota
27520         local pref="osd-zfs.$FSNAME-MDT0000."
27521
27522         # limit available space on MDS dataset to meet nospace issue
27523         # quickly. then ZFS 0.7.2 can use reserved space if asked
27524         # properly (using netfree flag in osd_declare_destroy()
27525         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27526         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27527                 gawk '{print $3}')
27528         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27529         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27530         let "usedkb=usedkb-freekb"
27531         let "freekb=freekb/2"
27532         if let "freekb > 5000"; then
27533                 let "freekb=5000"
27534         fi
27535         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27536         trap cleanup_805 EXIT
27537         mkdir_on_mdt0 $DIR/$tdir
27538         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27539                 error "Can't set PFL layout"
27540         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27541         rm -rf $DIR/$tdir || error "not able to remove"
27542         do_facet $SINGLEMDS zfs set quota=$old $fsset
27543         trap 0
27544 }
27545 run_test 805 "ZFS can remove from full fs"
27546
27547 # Size-on-MDS test
27548 check_lsom_data()
27549 {
27550         local file=$1
27551         local expect=$(stat -c %s $file)
27552
27553         check_lsom_size $1 $expect
27554
27555         local blocks=$($LFS getsom -b $file)
27556         expect=$(stat -c %b $file)
27557         [[ $blocks == $expect ]] ||
27558                 error "$file expected blocks: $expect, got: $blocks"
27559 }
27560
27561 check_lsom_size()
27562 {
27563         local size
27564         local expect=$2
27565
27566         cancel_lru_locks mdc
27567
27568         size=$($LFS getsom -s $1)
27569         [[ $size == $expect ]] ||
27570                 error "$file expected size: $expect, got: $size"
27571 }
27572
27573 test_806() {
27574         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27575                 skip "Need MDS version at least 2.11.52"
27576
27577         local bs=1048576
27578
27579         touch $DIR/$tfile || error "touch $tfile failed"
27580
27581         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27582         save_lustre_params client "llite.*.xattr_cache" > $save
27583         lctl set_param llite.*.xattr_cache=0
27584         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27585
27586         # single-threaded write
27587         echo "Test SOM for single-threaded write"
27588         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27589                 error "write $tfile failed"
27590         check_lsom_size $DIR/$tfile $bs
27591
27592         local num=32
27593         local size=$(($num * $bs))
27594         local offset=0
27595         local i
27596
27597         echo "Test SOM for single client multi-threaded($num) write"
27598         $TRUNCATE $DIR/$tfile 0
27599         for ((i = 0; i < $num; i++)); do
27600                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27601                 local pids[$i]=$!
27602                 offset=$((offset + $bs))
27603         done
27604         for (( i=0; i < $num; i++ )); do
27605                 wait ${pids[$i]}
27606         done
27607         check_lsom_size $DIR/$tfile $size
27608
27609         $TRUNCATE $DIR/$tfile 0
27610         for ((i = 0; i < $num; i++)); do
27611                 offset=$((offset - $bs))
27612                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27613                 local pids[$i]=$!
27614         done
27615         for (( i=0; i < $num; i++ )); do
27616                 wait ${pids[$i]}
27617         done
27618         check_lsom_size $DIR/$tfile $size
27619
27620         # multi-client writes
27621         num=$(get_node_count ${CLIENTS//,/ })
27622         size=$(($num * $bs))
27623         offset=0
27624         i=0
27625
27626         echo "Test SOM for multi-client ($num) writes"
27627         $TRUNCATE $DIR/$tfile 0
27628         for client in ${CLIENTS//,/ }; do
27629                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27630                 local pids[$i]=$!
27631                 i=$((i + 1))
27632                 offset=$((offset + $bs))
27633         done
27634         for (( i=0; i < $num; i++ )); do
27635                 wait ${pids[$i]}
27636         done
27637         check_lsom_size $DIR/$tfile $offset
27638
27639         i=0
27640         $TRUNCATE $DIR/$tfile 0
27641         for client in ${CLIENTS//,/ }; do
27642                 offset=$((offset - $bs))
27643                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27644                 local pids[$i]=$!
27645                 i=$((i + 1))
27646         done
27647         for (( i=0; i < $num; i++ )); do
27648                 wait ${pids[$i]}
27649         done
27650         check_lsom_size $DIR/$tfile $size
27651
27652         # verify truncate
27653         echo "Test SOM for truncate"
27654         $TRUNCATE $DIR/$tfile 1048576
27655         check_lsom_size $DIR/$tfile 1048576
27656         $TRUNCATE $DIR/$tfile 1234
27657         check_lsom_size $DIR/$tfile 1234
27658
27659         # verify SOM blocks count
27660         echo "Verify SOM block count"
27661         $TRUNCATE $DIR/$tfile 0
27662         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27663                 error "failed to write file $tfile"
27664         check_lsom_data $DIR/$tfile
27665 }
27666 run_test 806 "Verify Lazy Size on MDS"
27667
27668 test_807() {
27669         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27670         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27671                 skip "Need MDS version at least 2.11.52"
27672
27673         # Registration step
27674         changelog_register || error "changelog_register failed"
27675         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27676         changelog_users $SINGLEMDS | grep -q $cl_user ||
27677                 error "User $cl_user not found in changelog_users"
27678
27679         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27680         save_lustre_params client "llite.*.xattr_cache" > $save
27681         lctl set_param llite.*.xattr_cache=0
27682         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27683
27684         rm -rf $DIR/$tdir || error "rm $tdir failed"
27685         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27686         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27687         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27688         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27689                 error "truncate $tdir/trunc failed"
27690
27691         local bs=1048576
27692         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27693                 error "write $tfile failed"
27694
27695         # multi-client wirtes
27696         local num=$(get_node_count ${CLIENTS//,/ })
27697         local offset=0
27698         local i=0
27699
27700         echo "Test SOM for multi-client ($num) writes"
27701         touch $DIR/$tfile || error "touch $tfile failed"
27702         $TRUNCATE $DIR/$tfile 0
27703         for client in ${CLIENTS//,/ }; do
27704                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27705                 local pids[$i]=$!
27706                 i=$((i + 1))
27707                 offset=$((offset + $bs))
27708         done
27709         for (( i=0; i < $num; i++ )); do
27710                 wait ${pids[$i]}
27711         done
27712
27713         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27714         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27715         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27716         check_lsom_data $DIR/$tdir/trunc
27717         check_lsom_data $DIR/$tdir/single_dd
27718         check_lsom_data $DIR/$tfile
27719
27720         rm -rf $DIR/$tdir
27721         # Deregistration step
27722         changelog_deregister || error "changelog_deregister failed"
27723 }
27724 run_test 807 "verify LSOM syncing tool"
27725
27726 check_som_nologged()
27727 {
27728         local lines=$($LFS changelog $FSNAME-MDT0000 |
27729                 grep 'x=trusted.som' | wc -l)
27730         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27731 }
27732
27733 test_808() {
27734         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27735                 skip "Need MDS version at least 2.11.55"
27736
27737         # Registration step
27738         changelog_register || error "changelog_register failed"
27739
27740         touch $DIR/$tfile || error "touch $tfile failed"
27741         check_som_nologged
27742
27743         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27744                 error "write $tfile failed"
27745         check_som_nologged
27746
27747         $TRUNCATE $DIR/$tfile 1234
27748         check_som_nologged
27749
27750         $TRUNCATE $DIR/$tfile 1048576
27751         check_som_nologged
27752
27753         # Deregistration step
27754         changelog_deregister || error "changelog_deregister failed"
27755 }
27756 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27757
27758 check_som_nodata()
27759 {
27760         $LFS getsom $1
27761         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27762 }
27763
27764 test_809() {
27765         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27766                 skip "Need MDS version at least 2.11.56"
27767
27768         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27769                 error "failed to create DoM-only file $DIR/$tfile"
27770         touch $DIR/$tfile || error "touch $tfile failed"
27771         check_som_nodata $DIR/$tfile
27772
27773         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27774                 error "write $tfile failed"
27775         check_som_nodata $DIR/$tfile
27776
27777         $TRUNCATE $DIR/$tfile 1234
27778         check_som_nodata $DIR/$tfile
27779
27780         $TRUNCATE $DIR/$tfile 4097
27781         check_som_nodata $DIR/$file
27782 }
27783 run_test 809 "Verify no SOM xattr store for DoM-only files"
27784
27785 test_810() {
27786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27787         $GSS && skip_env "could not run with gss"
27788         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27789                 skip "OST < 2.12.58 doesn't align checksum"
27790
27791         set_checksums 1
27792         stack_trap "set_checksums $ORIG_CSUM" EXIT
27793         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27794
27795         local csum
27796         local before
27797         local after
27798         for csum in $CKSUM_TYPES; do
27799                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27800                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27801                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27802                         eval set -- $i
27803                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27804                         before=$(md5sum $DIR/$tfile)
27805                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27806                         after=$(md5sum $DIR/$tfile)
27807                         [ "$before" == "$after" ] ||
27808                                 error "$csum: $before != $after bs=$1 seek=$2"
27809                 done
27810         done
27811 }
27812 run_test 810 "partial page writes on ZFS (LU-11663)"
27813
27814 test_812a() {
27815         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27816                 skip "OST < 2.12.51 doesn't support this fail_loc"
27817
27818         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27819         # ensure ost1 is connected
27820         stat $DIR/$tfile >/dev/null || error "can't stat"
27821         wait_osc_import_state client ost1 FULL
27822         # no locks, no reqs to let the connection idle
27823         cancel_lru_locks osc
27824
27825         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27826 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27827         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27828         wait_osc_import_state client ost1 CONNECTING
27829         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27830
27831         stat $DIR/$tfile >/dev/null || error "can't stat file"
27832 }
27833 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27834
27835 test_812b() { # LU-12378
27836         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27837                 skip "OST < 2.12.51 doesn't support this fail_loc"
27838
27839         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27840         # ensure ost1 is connected
27841         stat $DIR/$tfile >/dev/null || error "can't stat"
27842         wait_osc_import_state client ost1 FULL
27843         # no locks, no reqs to let the connection idle
27844         cancel_lru_locks osc
27845
27846         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27847 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27848         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27849         wait_osc_import_state client ost1 CONNECTING
27850         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27851
27852         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27853         wait_osc_import_state client ost1 IDLE
27854 }
27855 run_test 812b "do not drop no resend request for idle connect"
27856
27857 test_812c() {
27858         local old
27859
27860         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27861
27862         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27863         $LFS getstripe $DIR/$tfile
27864         $LCTL set_param osc.*.idle_timeout=10
27865         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27866         # ensure ost1 is connected
27867         stat $DIR/$tfile >/dev/null || error "can't stat"
27868         wait_osc_import_state client ost1 FULL
27869         # no locks, no reqs to let the connection idle
27870         cancel_lru_locks osc
27871
27872 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27873         $LCTL set_param fail_loc=0x80000533
27874         sleep 15
27875         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27876 }
27877 run_test 812c "idle import vs lock enqueue race"
27878
27879 test_813() {
27880         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27881         [ -z "$file_heat_sav" ] && skip "no file heat support"
27882
27883         local readsample
27884         local writesample
27885         local readbyte
27886         local writebyte
27887         local readsample1
27888         local writesample1
27889         local readbyte1
27890         local writebyte1
27891
27892         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27893         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27894
27895         $LCTL set_param -n llite.*.file_heat=1
27896         echo "Turn on file heat"
27897         echo "Period second: $period_second, Decay percentage: $decay_pct"
27898
27899         echo "QQQQ" > $DIR/$tfile
27900         echo "QQQQ" > $DIR/$tfile
27901         echo "QQQQ" > $DIR/$tfile
27902         cat $DIR/$tfile > /dev/null
27903         cat $DIR/$tfile > /dev/null
27904         cat $DIR/$tfile > /dev/null
27905         cat $DIR/$tfile > /dev/null
27906
27907         local out=$($LFS heat_get $DIR/$tfile)
27908
27909         $LFS heat_get $DIR/$tfile
27910         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27911         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27912         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27913         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27914
27915         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27916         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27917         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27918         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27919
27920         sleep $((period_second + 3))
27921         echo "Sleep $((period_second + 3)) seconds..."
27922         # The recursion formula to calculate the heat of the file f is as
27923         # follow:
27924         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27925         # Where Hi is the heat value in the period between time points i*I and
27926         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27927         # to the weight of Ci.
27928         out=$($LFS heat_get $DIR/$tfile)
27929         $LFS heat_get $DIR/$tfile
27930         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27931         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27932         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27933         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27934
27935         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27936                 error "read sample ($readsample) is wrong"
27937         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27938                 error "write sample ($writesample) is wrong"
27939         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27940                 error "read bytes ($readbyte) is wrong"
27941         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27942                 error "write bytes ($writebyte) is wrong"
27943
27944         echo "QQQQ" > $DIR/$tfile
27945         echo "QQQQ" > $DIR/$tfile
27946         echo "QQQQ" > $DIR/$tfile
27947         cat $DIR/$tfile > /dev/null
27948         cat $DIR/$tfile > /dev/null
27949         cat $DIR/$tfile > /dev/null
27950         cat $DIR/$tfile > /dev/null
27951
27952         sleep $((period_second + 3))
27953         echo "Sleep $((period_second + 3)) seconds..."
27954
27955         out=$($LFS heat_get $DIR/$tfile)
27956         $LFS heat_get $DIR/$tfile
27957         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27958         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27959         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27960         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27961
27962         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27963                 4 * $decay_pct) / 100") -eq 1 ] ||
27964                 error "read sample ($readsample1) is wrong"
27965         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27966                 3 * $decay_pct) / 100") -eq 1 ] ||
27967                 error "write sample ($writesample1) is wrong"
27968         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27969                 20 * $decay_pct) / 100") -eq 1 ] ||
27970                 error "read bytes ($readbyte1) is wrong"
27971         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27972                 15 * $decay_pct) / 100") -eq 1 ] ||
27973                 error "write bytes ($writebyte1) is wrong"
27974
27975         echo "Turn off file heat for the file $DIR/$tfile"
27976         $LFS heat_set -o $DIR/$tfile
27977
27978         echo "QQQQ" > $DIR/$tfile
27979         echo "QQQQ" > $DIR/$tfile
27980         echo "QQQQ" > $DIR/$tfile
27981         cat $DIR/$tfile > /dev/null
27982         cat $DIR/$tfile > /dev/null
27983         cat $DIR/$tfile > /dev/null
27984         cat $DIR/$tfile > /dev/null
27985
27986         out=$($LFS heat_get $DIR/$tfile)
27987         $LFS heat_get $DIR/$tfile
27988         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27989         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27990         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27991         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27992
27993         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27994         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27995         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27996         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27997
27998         echo "Trun on file heat for the file $DIR/$tfile"
27999         $LFS heat_set -O $DIR/$tfile
28000
28001         echo "QQQQ" > $DIR/$tfile
28002         echo "QQQQ" > $DIR/$tfile
28003         echo "QQQQ" > $DIR/$tfile
28004         cat $DIR/$tfile > /dev/null
28005         cat $DIR/$tfile > /dev/null
28006         cat $DIR/$tfile > /dev/null
28007         cat $DIR/$tfile > /dev/null
28008
28009         out=$($LFS heat_get $DIR/$tfile)
28010         $LFS heat_get $DIR/$tfile
28011         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28012         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28013         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28014         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28015
28016         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28017         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28018         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28019         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28020
28021         $LFS heat_set -c $DIR/$tfile
28022         $LCTL set_param -n llite.*.file_heat=0
28023         echo "Turn off file heat support for the Lustre filesystem"
28024
28025         echo "QQQQ" > $DIR/$tfile
28026         echo "QQQQ" > $DIR/$tfile
28027         echo "QQQQ" > $DIR/$tfile
28028         cat $DIR/$tfile > /dev/null
28029         cat $DIR/$tfile > /dev/null
28030         cat $DIR/$tfile > /dev/null
28031         cat $DIR/$tfile > /dev/null
28032
28033         out=$($LFS heat_get $DIR/$tfile)
28034         $LFS heat_get $DIR/$tfile
28035         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28036         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28037         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28038         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28039
28040         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28041         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28042         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28043         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28044
28045         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28046         rm -f $DIR/$tfile
28047 }
28048 run_test 813 "File heat verfication"
28049
28050 test_814()
28051 {
28052         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28053         echo -n y >> $DIR/$tfile
28054         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28055         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28056 }
28057 run_test 814 "sparse cp works as expected (LU-12361)"
28058
28059 test_815()
28060 {
28061         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28062         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28063 }
28064 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28065
28066 test_816() {
28067         local ost1_imp=$(get_osc_import_name client ost1)
28068         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28069                          cut -d'.' -f2)
28070
28071         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28072         # ensure ost1 is connected
28073
28074         stat $DIR/$tfile >/dev/null || error "can't stat"
28075         wait_osc_import_state client ost1 FULL
28076         # no locks, no reqs to let the connection idle
28077         cancel_lru_locks osc
28078         lru_resize_disable osc
28079         local before
28080         local now
28081         before=$($LCTL get_param -n \
28082                  ldlm.namespaces.$imp_name.lru_size)
28083
28084         wait_osc_import_state client ost1 IDLE
28085         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28086         now=$($LCTL get_param -n \
28087               ldlm.namespaces.$imp_name.lru_size)
28088         [ $before == $now ] || error "lru_size changed $before != $now"
28089 }
28090 run_test 816 "do not reset lru_resize on idle reconnect"
28091
28092 cleanup_817() {
28093         umount $tmpdir
28094         exportfs -u localhost:$DIR/nfsexp
28095         rm -rf $DIR/nfsexp
28096 }
28097
28098 test_817() {
28099         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28100
28101         mkdir -p $DIR/nfsexp
28102         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28103                 error "failed to export nfs"
28104
28105         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28106         stack_trap cleanup_817 EXIT
28107
28108         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28109                 error "failed to mount nfs to $tmpdir"
28110
28111         cp /bin/true $tmpdir
28112         $DIR/nfsexp/true || error "failed to execute 'true' command"
28113 }
28114 run_test 817 "nfsd won't cache write lock for exec file"
28115
28116 test_818() {
28117         test_mkdir -i0 -c1 $DIR/$tdir
28118         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28119         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28120         stop $SINGLEMDS
28121
28122         # restore osp-syn threads
28123         stack_trap "fail $SINGLEMDS"
28124
28125         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28126         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28127         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28128                 error "start $SINGLEMDS failed"
28129         rm -rf $DIR/$tdir
28130
28131         local testid=$(echo $TESTNAME | tr '_' ' ')
28132
28133         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28134                 grep "run LFSCK" || error "run LFSCK is not suggested"
28135 }
28136 run_test 818 "unlink with failed llog"
28137
28138 test_819a() {
28139         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28140         cancel_lru_locks osc
28141         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28142         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28143         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28144         rm -f $TDIR/$tfile
28145 }
28146 run_test 819a "too big niobuf in read"
28147
28148 test_819b() {
28149         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28150         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28151         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28152         cancel_lru_locks osc
28153         sleep 1
28154         rm -f $TDIR/$tfile
28155 }
28156 run_test 819b "too big niobuf in write"
28157
28158
28159 function test_820_start_ost() {
28160         sleep 5
28161
28162         for num in $(seq $OSTCOUNT); do
28163                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28164         done
28165 }
28166
28167 test_820() {
28168         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28169
28170         mkdir $DIR/$tdir
28171         umount_client $MOUNT || error "umount failed"
28172         for num in $(seq $OSTCOUNT); do
28173                 stop ost$num
28174         done
28175
28176         # mount client with no active OSTs
28177         # so that the client can't initialize max LOV EA size
28178         # from OSC notifications
28179         mount_client $MOUNT || error "mount failed"
28180         # delay OST starting to keep this 0 max EA size for a while
28181         test_820_start_ost &
28182
28183         # create a directory on MDS2
28184         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28185                 error "Failed to create directory"
28186         # open intent should update default EA size
28187         # see mdc_update_max_ea_from_body()
28188         # notice this is the very first RPC to MDS2
28189         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28190         ret=$?
28191         echo $out
28192         # With SSK, this situation can lead to -EPERM being returned.
28193         # In that case, simply retry.
28194         if [ $ret -ne 0 ] && $SHARED_KEY; then
28195                 if echo "$out" | grep -q "not permitted"; then
28196                         cp /etc/services $DIR/$tdir/mds2
28197                         ret=$?
28198                 fi
28199         fi
28200         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28201 }
28202 run_test 820 "update max EA from open intent"
28203
28204 test_822() {
28205         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28206
28207         save_lustre_params mds1 \
28208                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28209         do_facet $SINGLEMDS "$LCTL set_param -n \
28210                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28211         do_facet $SINGLEMDS "$LCTL set_param -n \
28212                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28213
28214         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28215         local maxage=$(do_facet mds1 $LCTL get_param -n \
28216                        osp.$FSNAME-OST0000*MDT0000.maxage)
28217         sleep $((maxage + 1))
28218
28219         #define OBD_FAIL_NET_ERROR_RPC          0x532
28220         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28221
28222         stack_trap "restore_lustre_params < $p; rm $p"
28223
28224         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28225                       osp.$FSNAME-OST0000*MDT0000.create_count")
28226         for i in $(seq 1 $count); do
28227                 touch $DIR/$tfile.${i} || error "touch failed"
28228         done
28229 }
28230 run_test 822 "test precreate failure"
28231
28232 test_823() {
28233         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28234         local OST_MAX_PRECREATE=20000
28235
28236         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28237                 skip "Need MDS version at least 2.14.56"
28238
28239         save_lustre_params mds1 \
28240                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28241         do_facet $SINGLEMDS "$LCTL set_param -n \
28242                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28243         do_facet $SINGLEMDS "$LCTL set_param -n \
28244                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28245
28246         stack_trap "restore_lustre_params < $p; rm $p"
28247
28248         do_facet $SINGLEMDS "$LCTL set_param -n \
28249                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28250
28251         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28252                       osp.$FSNAME-OST0000*MDT0000.create_count")
28253         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28254                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28255         local expect_count=$(((($max/2)/256) * 256))
28256
28257         log "setting create_count to 100200:"
28258         log " -result- count: $count with max: $max, expecting: $expect_count"
28259
28260         [[ $count -eq expect_count ]] ||
28261                 error "Create count not set to max precreate."
28262 }
28263 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28264
28265 test_831() {
28266         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28267                 skip "Need MDS version 2.14.56"
28268
28269         local sync_changes=$(do_facet $SINGLEMDS \
28270                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28271
28272         [ "$sync_changes" -gt 100 ] &&
28273                 skip "Sync changes $sync_changes > 100 already"
28274
28275         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28276
28277         $LFS mkdir -i 0 $DIR/$tdir
28278         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28279
28280         save_lustre_params mds1 \
28281                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28282         save_lustre_params mds1 \
28283                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28284
28285         do_facet mds1 "$LCTL set_param -n \
28286                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28287                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28288         stack_trap "restore_lustre_params < $p" EXIT
28289
28290         createmany -o $DIR/$tdir/f- 1000
28291         unlinkmany $DIR/$tdir/f- 1000 &
28292         local UNLINK_PID=$!
28293
28294         while sleep 1; do
28295                 sync_changes=$(do_facet mds1 \
28296                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28297                 # the check in the code is racy, fail the test
28298                 # if the value above the limit by 10.
28299                 [ $sync_changes -gt 110 ] && {
28300                         kill -2 $UNLINK_PID
28301                         wait
28302                         error "osp changes throttling failed, $sync_changes>110"
28303                 }
28304                 kill -0 $UNLINK_PID 2> /dev/null || break
28305         done
28306         wait
28307 }
28308 run_test 831 "throttling unlink/setattr queuing on OSP"
28309
28310 #
28311 # tests that do cleanup/setup should be run at the end
28312 #
28313
28314 test_900() {
28315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28316         local ls
28317
28318         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28319         $LCTL set_param fail_loc=0x903
28320
28321         cancel_lru_locks MGC
28322
28323         FAIL_ON_ERROR=true cleanup
28324         FAIL_ON_ERROR=true setup
28325 }
28326 run_test 900 "umount should not race with any mgc requeue thread"
28327
28328 # LUS-6253/LU-11185
28329 test_901() {
28330         local old
28331         local count
28332         local oldc
28333         local newc
28334         local olds
28335         local news
28336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28337
28338         # some get_param have a bug to handle dot in param name
28339         cancel_lru_locks MGC
28340         old=$(mount -t lustre | wc -l)
28341         # 1 config+sptlrpc
28342         # 2 params
28343         # 3 nodemap
28344         # 4 IR
28345         old=$((old * 4))
28346         oldc=0
28347         count=0
28348         while [ $old -ne $oldc ]; do
28349                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28350                 sleep 1
28351                 ((count++))
28352                 if [ $count -ge $TIMEOUT ]; then
28353                         error "too large timeout"
28354                 fi
28355         done
28356         umount_client $MOUNT || error "umount failed"
28357         mount_client $MOUNT || error "mount failed"
28358         cancel_lru_locks MGC
28359         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28360
28361         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28362
28363         return 0
28364 }
28365 run_test 901 "don't leak a mgc lock on client umount"
28366
28367 # LU-13377
28368 test_902() {
28369         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28370                 skip "client does not have LU-13377 fix"
28371         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28372         $LCTL set_param fail_loc=0x1415
28373         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28374         cancel_lru_locks osc
28375         rm -f $DIR/$tfile
28376 }
28377 run_test 902 "test short write doesn't hang lustre"
28378
28379 # LU-14711
28380 test_903() {
28381         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28382         echo "blah" > $DIR/${tfile}-2
28383         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28384         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28385         $LCTL set_param fail_loc=0x417 fail_val=20
28386
28387         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28388         sleep 1 # To start the destroy
28389         wait_destroy_complete 150 || error "Destroy taking too long"
28390         cat $DIR/$tfile > /dev/null || error "Evicted"
28391 }
28392 run_test 903 "Test long page discard does not cause evictions"
28393
28394 test_904() {
28395         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28396         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28397                 grep -q project || skip "skip project quota not supported"
28398
28399         local testfile="$DIR/$tdir/$tfile"
28400         local xattr="trusted.projid"
28401         local projid
28402         local mdts=$(comma_list $(mdts_nodes))
28403         local saved=$(do_facet mds1 $LCTL get_param -n \
28404                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28405
28406         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28407         stack_trap "do_nodes $mdts $LCTL set_param \
28408                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28409
28410         mkdir -p $DIR/$tdir
28411         touch $testfile
28412         #hide projid xattr on server
28413         $LFS project -p 1 $testfile ||
28414                 error "set $testfile project id failed"
28415         getfattr -m - $testfile | grep $xattr &&
28416                 error "do not show trusted.projid when disabled on server"
28417         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28418         #should be hidden when projid is 0
28419         $LFS project -p 0 $testfile ||
28420                 error "set $testfile project id failed"
28421         getfattr -m - $testfile | grep $xattr &&
28422                 error "do not show trusted.projid with project ID 0"
28423
28424         #still can getxattr explicitly
28425         projid=$(getfattr -n $xattr $testfile |
28426                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28427         [ $projid == "0" ] ||
28428                 error "projid expected 0 not $projid"
28429
28430         #set the projid via setxattr
28431         setfattr -n $xattr -v "1000" $testfile ||
28432                 error "setattr failed with $?"
28433         projid=($($LFS project $testfile))
28434         [ ${projid[0]} == "1000" ] ||
28435                 error "projid expected 1000 not $projid"
28436
28437         #check the new projid via getxattr
28438         $LFS project -p 1001 $testfile ||
28439                 error "set $testfile project id failed"
28440         getfattr -m - $testfile | grep $xattr ||
28441                 error "should show trusted.projid when project ID != 0"
28442         projid=$(getfattr -n $xattr $testfile |
28443                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28444         [ $projid == "1001" ] ||
28445                 error "projid expected 1001 not $projid"
28446
28447         #try to set invalid projid
28448         setfattr -n $xattr -v "4294967295" $testfile &&
28449                 error "set invalid projid should fail"
28450
28451         #remove the xattr means setting projid to 0
28452         setfattr -x $xattr $testfile ||
28453                 error "setfattr failed with $?"
28454         projid=($($LFS project $testfile))
28455         [ ${projid[0]} == "0" ] ||
28456                 error "projid expected 0 not $projid"
28457
28458         #should be hidden when parent has inherit flag and same projid
28459         $LFS project -srp 1002 $DIR/$tdir ||
28460                 error "set $tdir project id failed"
28461         getfattr -m - $testfile | grep $xattr &&
28462                 error "do not show trusted.projid with inherit flag"
28463
28464         #still can getxattr explicitly
28465         projid=$(getfattr -n $xattr $testfile |
28466                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28467         [ $projid == "1002" ] ||
28468                 error "projid expected 1002 not $projid"
28469 }
28470 run_test 904 "virtual project ID xattr"
28471
28472 complete $SECONDS
28473 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28474 check_and_cleanup_lustre
28475 if [ "$I_MOUNTED" != "yes" ]; then
28476         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28477 fi
28478 exit_status